从辅助线程调用MainThread上的事件 [英] Invoke event on MainThread from worker thread

查看:221
本文介绍了从辅助线程调用MainThread上的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从主线程中的辅助线程调用事件时遇到麻烦.事件处理程序不在主线程上执行.谁能给我一些有关我做错事情的提示.

I'm having trouble invoking an event from a secondary thread in the main thread. The event handler is not executed on main thread. Can anyone give me some pointers on what I'm doing wrong.

谢谢

namespace ThreadSyncExample
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("MainThread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);

      Execute execThe = new Execute();
      execThe.FinishedThread += (src, arg) =>
      {
        //This shoould be executed on MainThread right?
        Console.WriteLine("Thread Id: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
      };

      execThe.Run();
      Console.ReadKey();
    }

  }


  class Execute
  {
    public void Run()
    {
      Thread exec = new Thread(() =>
      {
        Console.WriteLine("Worker Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        OnFinishedThread();
      });

      exec.Start();
    }

    public event EventHandler FinishedThread;
    protected virtual void OnFinishedThread()
    {
      if (null != FinishedThread)
      {
        EventArgs args = new EventArgs();
        FinishedThread(this, EventArgs.Empty);
      }
    }
  }
}

推荐答案

C#事件基本上只是一个易于使用的委托集合,并且触发"事件只会导致运行时循环遍历所有委托并触发他们一次一个.

C# events are basically just an easy-to-use collection of delegates and "firing" an event just causes the runtime to loop through all of the delegates and fire them one at a time.

因此,您的OnFinishedThread事件处理程序将在Worker线程上被调用.

So your OnFinishedThread event handler is getting called on the Worker thread.

如果要在主线程上进行事件,则必须对其进行Invoke().

If you want your event on the main thread, you have to Invoke() it.

您似乎无权访问表单或WPF(因此也无权访问Invoke())

It appears that you don't have access to forms, or WPF (so you don't have access to Invoke() either)

因此,您必须通过线程同步过程手动封送对主线程的调用.通常很痛苦.

So you have to manually marshall the call to the main thread by thread synchronization process. It's generally a pain.

最简单的解决方案可能是仅使用 BackgroundWorker ,因为您不再需要手动封送对主线程的调用.

Probably the easiest solution would be to simply use a BackgroundWorker because this way you no longer need to manualy marshal the calls to the main thread.

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
{
    // call the XYZ function
    e.Result = XYZ();
};
worker.RunWorkerCompleted += (sender, e) =>
{
    // use the result of the XYZ function:
    var result = e.Result;
    // Here you can safely manipulate the GUI controls
};
worker.RunWorkerAsync();

这篇关于从辅助线程调用MainThread上的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆