2011-10-25 12 views
5

Piszę aplikację Windows Forms w języku C#, która wykonuje wiele długotrwałych procedur za jednym kliknięciem przycisku. To powoduje, że GUI zamarza do momentu wykonania. Ponadto, podczas wykonywania, loguję informacje o statusie & status do pola listy. Jednak do zakończenia realizacji status nie jest aktualizowany w polu listy. W jaki sposób powinienem kodować, aby status był aktualizowany w polu listy równolegle z wykonaniem i aby GUI nie zamarzał.Asynchroniczne wykonywanie w oknach formularze

Jestem nowy w wątkach. Czy możesz podać przykład tego, jak to się robi?

Z góry dziękuję za pomoc.

Odpowiedz

12

Najprostszym, ale skutecznym sposobem radzenia sobie z tymi scenariuszami, jest użycie BackgroundWorker.

Umieszczasz swój ciężki kod w programie obsługi zdarzeń DoWork i aktualizujesz GUI za pomocą obsługi zdarzeń ProgressChanged.

można znaleźć tutorial here
lub nawet lepiej zrobili „jak” na msdn
Jeśli masz bardziej szczegółowe pytania po przeczytaniu go, będę szczęśliwy zobowiązać.

+0

Wielkie dzięki. Rozwiązanie jest bardzo pomocne. – RSP

4

Jak Pawian powiedziała jedna droga jest podejście tle Pracownik inny sposób, jeśli używasz .Net 4 lub powyżej może być użycie Task klasa

klasa Zadanie ułatwia wykonywanie kodu na tle wątku UI i ile potrzeba . Korzystanie z klasy Task można uniknąć pisania dodatkowego kodu zachodzącego wydarzeń i wywołania zwrotne za pomocą Task Continuation

Reed Copsey Jr ma bardzo dobrą series na równoległoœci .Net również spojrzeć na to

na przykład Synchroniczny sposób robienia rzeczy może być

//bad way to send emails to all people in list, that will freeze your UI 
foreach (String to in toList) 
{ 
    bool hasSent = SendMail(from, "password", to, SubjectTextBox.Text, BodyTextBox.Text); 
    if (hasSent) 
    { 
     OutPutTextBox.appendText("Sent to: " + to); 
    } 
    else 
    { 
     OutPutTextBox.appendText("Failed to: " + to); 
    } 
} 

//good way using Task class which won't freeze your UI 
string subject = SubjectTextBox.Text; 
string body = BodyTextBox.Text; 
var ui = TaskScheduler.FromCurrentSynchronizationContext(); 
List<Task> mails = new List<Task>(); 
foreach (string to in toList) 
{ 
    string target = to; 
    var t = Task.Factory.StartNew(() => SendMail(from, "password", target, subject, body)) 
    .ContinueWith(task => 
    { 
     if (task.Result) 
     { 
      OutPutTextBox.appendText("Sent to: " + to); 
     } 
     else 
     { 
      OutPutTextBox.appendText("Failed to: " + to); 
     } 
    }, ui); 
} 
+0

Należy zachować ostrożność, ponieważ biblioteka równoległa nie zawsze tworzy nowy wątek. Na przykład Parallel.Foreach nie utworzy nici dla każdej innej pętli. –