主线程上的.NET事件 [英] .NET event on main thread

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

问题描述

我想将一个事件从工作线程引发到主线程。我希望事件调用的委托在主线程上执行。在.NET中最简单的方法是什么?



I want to raise an event from a worker thread to the main thread. I want the delegate that gets called by the event to be executed on the main thread. What's the simplest way of doing it in .NET?

//pseudocode
void MainThread() {
   while(true) {
      // doing something
      // here I have to call something periodically to be able to get OnEvent executed
   }
}

void OnEvent() {
   // do something on event on the main thread
}

void WorkerThread() {
   while(true) {
   // if something happened, raise event to main thread
   }
}





我的应用程序是控制台应用程序。



My application is console application.

推荐答案

首先,让我们关闭事件的问题。您不能从除该事件的声明类型之外的任何地方调用事件,甚至不能从派生类调用。这是.NET的一个重要的万无一失的功能。最有可能的意思是,在某种.NET FCL类型中声明事件。如果是这样,那么你无法调用它,除了它已被调用的方式(鼠标单击等)。你永远不需要这样做。我在过去的答案中解释了这一切:

在C ++ CLI中将事件作为函数调用 [ ^ ],
c#网络窗体 [ ^ ]。



如果你通过调用活动向我解释你要达到的目的,我会告诉你你真正需要做什么。



现在,请看我对这个问题的评论;你应该指定主线程正在做什么。如果这是一个WPF应用程序的线程或 System.Windows.Forms.Application ,答案很简单:

你不能调用任何与之相关的东西来自非UI线程的UI。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

使用Treeview扫描仪和MD5的问题 [ ^ ]。



另请参阅有关线程的更多参考资料:

如何让keydown事件在不同的操作上运行vb.net中的线程 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



如果你的主线程不同,你需要设计线程方法来实现类似的行为。只有这样,您才能将任何内容委托给该线程。我在文章中解释了如何做到这一点:用于线程通信的简单阻塞队列和线程间调用 [ ^ ]。



如果您使用的是.NET 4.0或更高版本,则可以使用更高效的类 System.Collections.Concurrent.BlockingCollection< T>

http://msdn.microsoft.com/en-us/library/dd267312%28v=vs.110%29.aspx [ ^ ]。



注意 T 可以是委托,实现非常接近 Invoke / BeginInvoke 。再次,请阅读上面引用的文章,看看如何做到这一点。



所以,我认为这次你有100%全面的答案,但是,下次,注意我对问题的评论并提供更多相关信息。



-SA
First, let's close the problem of events. You cannot ever invoke an event from anywhere except the declaring type of that event, not even from derived class. This is an important fool-proof feature of .NET. Most likely, you mean the event declared in some .NET FCL type. If so, you have no a way to invoke it then, except the ways it is already being invoked (mouse click, and so on). And you never really need to do it. I explained it all in my past answers:
Calling an Event as a Function in C++ CLI[^],
c# networking windows form[^].

If you explain to me what you though to achieve by invoking the event, I'll tell you what you really need to do.

Now, please see my comment to the question; you should have specified what you main thread is doing. If this is a thread of a WPF application or System.Windows.Forms.Application, the answer is simple:
You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

If your main thread is something different, you would need to design the thread method to implement similar behavior. Only then you will be able to delegate anything to that thread. I explained how to do it in my article: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

If you are using .NET 4.0 or later, you can use more efficient class System.Collections.Concurrent.BlockingCollection<T>:
http://msdn.microsoft.com/en-us/library/dd267312%28v=vs.110%29.aspx[^].

Note that T can be a delegate, to implement the mechanism very close to Invoke/BeginInvoke. Again, read my article referenced above, to see how to do it.

So, I think you got a 100% comprehensive answer this time, but, next time, pay attention for my comment to the question and provide more relevant information.

—SA


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

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