简体   繁体   English

将事件从任务提升到UI线程

[英]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. 我一直在尝试确定从异步任务操作UI的正确方法。 My application has become cluttered with threaded Invokes and BeginInvokes. 我的应用程序变得很混乱,与线程调用和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 . 我正在尝试减轻这种混乱情况,并通过利用C#async和await在UI上提供更多响应。

Somewhere on the UI thread I initialize IProgress event handler and pass it to an asynchronous function called DoInfiniteWorkAsync . 在UI线程的某个位置,我初始化了IProgress 事件处理程序 ,并将其传递给名为DoInfiniteWorkAsync的异步函数。 This function runs infinitely in a background task but often has the need to update portions of the UI. 此功能在后台任务中无限运行,但是经常需要更新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. 我的DoInfiniteWorkAsync函数在运行其任务时使用传入的UIEventHandler来报告UIEventMessages

    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? 这是从长时间运行的后台线程更新UI线程的正确方法吗? The fact that my event handler datatype (IProgress) is specifically directed at progress reporting is making me feel like I'm missing the point. 我的事件处理程序数据类型(IProgress)是专门针对进度报告的事实,这让我觉得我没抓住重点。

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. 然后,用eventMessage填充字符串并调用一个方法来调用数据。

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

This is the method Msg(): 这是Msg()方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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