发送要在其他线程上调用的方法 [英] send a method to be invoked on other thread

查看:107
本文介绍了发送要在其他线程上调用的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个线程:t1和t2.
t1是主线程,它已经创建了t2线程.
创建t2之后,t1继续做一些工作.在t2上,有一点我想在t1线程上执行一个代码,而t2继续执行他的其余代码.有没有办法让t2告诉t1停止您现在正在做的事情,运行这段代码,然后再返回做您的工作"?
我知道,当您想使用Control.Invoke()或SynchronizationContext类在Windows窗体应用程序中的UI线程上运行代码时,这是可能的,但是是否有任何常规线程方式? /div>

当然,您可以在另一个线程上(更确切地说,是委托实例)调用方法,但是...

您的停止您正在做的事情,运行此代码,然后返回以完成工作"听起来像是线程抢占.您的意思是,t1应该与要中断的代码无关吗? - 这听起来像.如果是这样,那不是不可能的,就不能赋予它任何意义.让我们考虑一下.线程的抢占一直在发生-这就是线程工作的方式.线程切换可以是协作的,也可以在硬件中断时发生,并且在所有情况下都可以抢占线程,中断其执行,保存其上下文并执行其他一些代码.一段时间后,可以安排同一线程再次执行.从该线程的角度来看,什么都没发生-从相同环境中的同一点继续执行.基本上,线程就像执行过程一样感觉"到了.但是,当线程关闭时,正在运行什么代码? 除了定义之外,该线程什么也没有.执行中断过程,最终执行线程调度程序,维护线程所需的系统核心中的任何内容,以及其他线程.只需考虑一下-这就是线程化思想的核心. 线程被抢占时,当时正在执行的不是该线程.

现在,不要被线程调用的想法所迷惑.它只是意味着一个线程将某些实例引用的委托提供给其他经过特殊设计的线程,以接受这些实例并调用它们.这样的线程的一个示例是System.Windows.Forms或WPF的UI线程,但原则上可以是其他任何线程.继续阅读;我会解释它是如何工作的.首先,要了解UI线程上调用的工作方式,请阅读我过去关于该主题的答案:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5问题 [ http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx [
要对UI线程以外的其他线程使用线程间调用,您需要专门设计该线程以接受这些委托实例并调用它们.特别是,该线程需要有一个主处理循环和一个队列,其他线程可以在该队列中提供委托实例.如果您需要了解它的工作原理,请阅读我关于此主题的小文章,其中包括完整的源代码和用法示例:
用于线程通信和线程间调用的简单阻塞队列 [ ^ ].

—SA


I have two threads : t1 and t2.
t1 is the main thread, and it has created the t2 thread.
After creating t2, t1 continue doing some work. on t2, there is at some point a code that I want to be executed on the t1 thread, while t2 continue to the rest of his code. is there a way that t2 can tell t1 "stop what you''r doing now, run this code, and than return to do your work " ?
I know that this is possible when you want to run code on the UI Thread in Windows Form Application,using Control.Invoke() or SynchronizationContext class, but is there any regular threads way ?

解决方案

Of course you can invoke a method on the other thread, more exactly, a delegate instance, but…

Your "stop what you''re doing now, run this code, and than return to do your work" sounds like thread preemption. Do you mean, t1 should be agnostic to the code to be executed when it is to be interrupted? — it sounds like. If so, not that this is impossible, it cannot be attributed any meaning. Let''s think about that. Preemption of a thread happens all the time — this is how threading works. Thread switching can be cooperative or can happen on hardware interrupts, and in all cases a thread can be preempted, its execution is interrupted, its context is saved, and some other code is executed. After a while, the same thread can be scheduled for execution again. From the perspective of this thread, nothing happened — execution is continued from the same point in the same environment. Basically, a thread "feels" like it is being executed along. But what code is running when a thread is switched off? Anything but this thread, by definition. Interrupt procedure is executed, eventually a thread scheduler, anything in the system core needed to maintain threading, and other threads. Just think about it — this is the heart of the idea of threading. When a thread is preempted, what is being executed at that time is not this thread.

Now, don''t be fooled by the idea of thread invocation. It simply means that one thread feeds some delegate instanced to some other thread specially designed to accept those instances and invoke them. An example of such thread is a UI thread, either System.Windows.Forms or WPF, but in principle it can be anything else. Keep reading; and I''ll explain how it works. First, to get an idea on how invocation works on the UI threads, please read my past answers on this topic:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

Many developers have been confused by the fact the the Invoke/BeginInvoke methods always works somehow, even if there is no UI thread. This is nothing more than the fool-proof design of the System.Windows.Threading.Dispatcher (please see http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx[^]). It is designed to invoke "dispatched" delegate instance in all cases, but in can be trivially invoked on the same thread, as simple as that.

To use inter-thread invocation to a thread other then a UI thread, you need to specially design that thread to accept those delegate instances and invoke them. In particular, that thread needs to have a main processing loop and a queue where other threads can feed the delegate instances. If you need to understand how it works, please read my small article on this topic, complete with full source code and usage samples:
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

—SA


这篇关于发送要在其他线程上调用的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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