RSP
RSP

Reputation: 231

Asynchronous Execution in windows forms

I'm writting a Windows Forms application in C# that executes a lot of long-running procedures on a single button click. This make the GUI to freeze till the execution. Also, during the execution, i'm logging the information & status to a List Box. However, untill the execution is complete, the status is not getting updated in the list box. How should i code so that the status is getting updated in list box in parallel with the execution and so that the GUI doesn't freeze.

I'm new to threading. Can you please give some example of how this is done?

Thanks in advance for your help.

Upvotes: 5

Views: 15717

Answers (2)

Haris Hasan
Haris Hasan

Reputation: 30097

As Baboon said one way to go is Background worker approach another way if you are using .Net 4 or above could be to use Task class

Task class simplifies the execution of code on background and UI thread as needed. Using Task class you can avoid writing extra code of setting events and callbacks by using Task Continuation

Reed Copsey, Jr. has a very good series on Parallelism on .Net also take a look at it

for example a synchronous way of doing things can be

//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);
 }

Upvotes: 4

Louis Kottmann
Louis Kottmann

Reputation: 16618

The simplest yet efficient way to handle these scenarios, is to use a BackgroundWorker.

You put your heavy code in the DoWork event handler, and update your GUI through the ProgressChanged event handler.

You can find a tutorial here
Or even better they made a "how to" at msdn
If you have more specific questions after reading it, i'll be happy to oblige.

Upvotes: 12

Related Questions