简体   繁体   中英

Raise Events to the UI thread from a Task

I have been trying to determine the proper approach to manipulate the UI from an asynchronous task. My application has become cluttered with threaded Invokes and BeginInvokes. I am trying to alleviate this clutter as well as provide a bit more responsiveness on the UI by taking advantage of C# async and await .

Somewhere on the UI thread I initialize IProgress event handler and pass it to an asynchronous function called DoInfiniteWorkAsync . This function runs infinitely in a background task but often has the need to update portions of the UI.

   private void Form1_Load(object sender, EventArgs e)
   {
       // Create a UIEventHandler on our UI thread.
       Progress<string> UIEventHandler = new Progress<string>();
       UIEventHandler.ProgressChanged += UIEventHandler_CommandRaised;
       // Pass the UIEventHandler to our Asyncronous task.
       DoInfiniteWorkAsync(UIEventHandler);

   }
   void UIEventHandler_EventRaised(object sender, string e)
   {
       string eventMessage = e;
       // Update UI based on the event message.
   }

My DoInfiniteWorkAsync function uses the passed in UIEventHandler to report UIEventMessages while running its task.

    private async Task DoInfiniteWorkAsync(IProgress<string> UIEventHandler)
    {
        await Task.Run(() =>
        {
            // 24/7 running tasks. 
            // Sets a UIEventMessage to signal UI thread to do something.
            UIEventHandler.Report(UIEventMessage);
        });
    }

Is this the proper way to be updating the UI thread from a long running background thread? The fact that my event handler datatype (IProgress) is specifically directed at progress reporting is making me feel like I'm missing the point.

To bring in data from one asynchronous thread to another you have to invoke it.

Define in your class a field of property:

    string _readData = null;

Then fill the string with the eventMessage and call a method to invoke the data.

string eventMessage = e;
_readData = eventMessage;
Msg();

This is the method Msg():

    private void Msg()
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new MethodInvoker(Msg));
        }
        else
        {
            textBox2.Text = textBox2.Text + Environment.NewLine + " >> " + _readData;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM