2013-08-12 12 views
5

Szukam od pewnego czasu odpowiedzi na mój konkretny problem bez powodzenia.Zamykanie formularza utworzonego w innym wątku

Mam zadanie w moim programie, które zajmuje kilka sekund i chcę pokazać nowy formularz podczas wykonywania tego zadania. Nowy formularz ma pasek ładowania i trochę tekstu.

Muszę pokazać nowy formularz równolegle do zadania, w przeciwnym razie zadanie nie rozpocznie się do momentu zamknięcia nowego formularza.

To rozwiązanie mam teraz:

private void loadingBar() 
{ 
    frmLoading frm = new frmLoading("Please wait while the database is being backed up", "This might take several days."); 
    frm.ShowDialog(); 

} 

public void Backup() 
{ 
    Thread load = new Thread(new ThreadStart(loadingBar)); 
    load.Start(); 

    ///Execute a task. 

    load.Abort(); 
} 

Tak, to działa OK, ale moje pytanie brzmi: nie byłoby lepiej byłoby, aby zamknąć formularz „frm” w obciążeniu gwintem zrobić to się zatrzymuje?

+1

Traktuj to jak działa pasek postępu. Uruchom "proces" jako podrzędny wątek tła do formularza, który chcesz pokazać. Następnie wywołaj ten formularz z wątku "Main". Główny wątek zostanie zablokowany z pokazanym formularzem ładowania, a formularz ładowania uruchomi coś jako wątek w tle. W ten sposób sam formularz ładowania może śledzić proces i zamknąć się po jego zakończeniu. – Nevyn

+3

@Dave Dlaczego po prostu nie użyć 'backgroundWorker'? Również - Możesz chcieć rozważyć umieszczenie tego kodu dla wątku w instrukcji 'Using()', to następnie się wyrzuci po zakończeniu. – Hexie

+1

Jest to zasadniczo niewłaściwa rzecz. Istnieje kilka bardzo nieprzyjemnych trybów awaryjnych wyświetlania interfejsu użytkownika w wątku roboczym.Trzeba to zrobić odwrotnie, wyświetlić okno "ładowanie" w wątku UI, wykonać kopię zapasową w wątku roboczym. –

Odpowiedz

1

Możesz zadeklarować formularz na poziomie klasy, a następnie zamknąć go przy pomocy invoke. MSDN-Windows Forms Invoke

Jak to:

public class Class1 
{ 
    private Form myForm; 

    public Class1() 
    { 
     myForm = new Form(); 
    } 

    public void DoSomeWork() 
    { 
     // =================================================== 
     // Do Some Work... 
     // =================================================== 

     myForm.Invoke(new MethodInvoker(this.Hide)); 
    } 

    public void Hide() 
    { 
     myForm.Hide(); 
    } 

    public void Backup() 
    { 
     myForm.ShowDialog(); 

     Thread load = new Thread(new ThreadStart(DoSomeWork)); 
     load.Start(); 
    } 
} 
2

Można to zrobić na kilka sposobów ...

1 - Można zrobić jak sugeruje BendEg i powołać ty frmClose raz jesteś gotowy

Coś jak;

Invoke(new Action(Close)); 

lub

Invoke(new Action(() => frmMain.Close())); 

2 - A może po prostu użyć pracownika tła;

Najprostszym sposobem na wykazanie tego jest dodanie do formularza BackgroundWorker i wykorzystanie dostarczonych zdarzeń;

public Form1() 
{ 
    InitializeComponent(); 
    backgroundWorker1.RunWorkerAsync(); 

    MessageBox.Show(@"Please wait while the database is being backed up", @"This might take several days."); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Debug.WriteLine("Running"); //Execute a task 
} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    Debug.WriteLine("Ended"); //Dispose of any objects you'd like (close yor form etc.) 
} 

Mam nadzieję, że to pomoże.

0

Myślę, że to pomoże (jeśli ja zrozumiałem prawej):

   Parallel.Invoke(() => somemethod(),() => 
       { 
        someothertaskmethod(); 
       }); 

umieściłem metody jak np wykazania 2 uruchomionych zadań.

Ty nee użyć właściwego using using System.Threading.Tasks;

1

myślę, to może pracować dla Ciebie.

void YourMethod() 
{ 
    WaitForm wf = new WaitForm(); 
    Invoke(new PleaseWaitDelegate(Launch),wf); 
    bool val = BoolMethodDoWork(); 
    Invoke(new PleaseWaitDelegate(Close), wf); 
       if(val) 
       { 
        MessageBox.Show("Success!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
        return; 
       } 
       MessageBox.Show("Damn!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
} 
delegate void PleaseWaitDelegate(Form form); 
     void Launch(Form form) 
     { 
      new System.Threading.Thread(()=> form. ShowDialog()).Start(); 
     } 

     void Close(Form form) 
     { 
      form.Close(); 
     } 
Powiązane problemy