Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating UI from events using asyc await

Tags:

I am trying to understand how to update a UI from an event while using async/await pattern. Below is the test code I am using on a WinForm app. I am not even sure this is the right way to go about it. What is necessary to allow the pwe_StatusUpdate method to update the UI? The cross-thread operation error is thrown there.

Thanks for reading.

 // calling code     ProcessWithEvents pwe = new ProcessWithEvents();     pwe.StatusUpdate += pwe_StatusUpdate;     await pwe.Run();     void pwe_StatusUpdate(string updateMsg)     {       // Error Here: Cross-thread operation not valid: Control '_listBox_Output' accessed from a thread other than the thread it was created on.       _listBox_Output.Items.Add(updateMsg);     } 

-

// Class with long running process and event     public delegate void StatusUpdateHandler(string updateMsg);   public class ProcessWithEvents   {     public event StatusUpdateHandler StatusUpdate;      public async Task Run()     {         await Task.Run(() =>         {             for (int i = 0; i < 10; i++)                 {                      RaiseUpdateEvent(String.Format("Update {0}", i));                      Thread.Sleep(500);                 }             });          }          private void RaiseUpdateEvent(string msg)         {         if (StatusUpdate != null)             StatusUpdate(msg);         }    } 

-

like image 762
ChiliYago Avatar asked Jul 13 '13 14:07

ChiliYago


People also ask

Does async await block UI?

Using async/await relies on suspending functions, instead of blocking threads, which provides clean code, without the risk of blocking the user interface.

Can an async method run on the UI thread of a Windows Forms app?

You can start an async operation from the UI thread, await it without blocking the UI thread, and naturally resume on the UI thread when it's done.

Can async method run on the UI thread?

@pm100 The method they're calling is an asyncrhonous method that interacts with the UI, and as such needs to be run on the UI thread. It's incorrect to run it in a non-UI thread. It will never work if you do that. It needs to be run in the UI thread.

Is await async the same as sync?

The differences between asynchronous and synchronous include: Async is multi-thread, which means operations or programs can run in parallel. Sync is single-thread, so only one operation or program will run at a time. Async is non-blocking, which means it will send multiple requests to a server.


1 Answers

The async pattern has support for progress updates.

In short, your async method can take an IProgress<T>, and your calling code passes in an implementation of that interface (usually Progress<T>).

public class ProcessWithUpdates {   public async Task Run(IProgress<string> progress)   {     await Task.Run(() =>     {       for (int i = 0; i < 10; i++)       {         if (progress != null)           progress.Report(String.Format("Update {0}", i));         Thread.Sleep(500);       }     });   } }  // calling code ProcessWithUpdates pwp = new ProcessWithUpdates(); await pwp.Run(new Progress<string>(pwp_StatusUpdate)); 
like image 75
Stephen Cleary Avatar answered Sep 23 '22 21:09

Stephen Cleary