如何使用事件跨线程? [英] How to use events to cross threads?

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

问题描述

我有一个对象启动一个线程来执行进程。其中一个步骤

在这个线程中通过Delegate.BeginInvoke启动12个其他线程到

进程。启动这12个线程后,主线程等待。在每个子线程完成

时,mainthread检查所有12个线程对象是否为
,看看它们是否完成。如果是的话,举起一个说我们已经完成的事件。


所以,它有点像这样:


ProcessThread

- 创建一个ProcessObject

- ProcessObject Execute创建一个包含12个SubProcessObjects的列表

- 调用12个新的SubProcessThreads

- SubProcessObject执行

- SubProcessObject设置已完成 flag

- 结束例程检查SubProcessObject列表以查看是否所有

已完成标志

- 如果是这样,将事件提升到主进程继续下一个ProcessObject


问题是,我不认为接收-main-thread实际上是在主线程上执行
。我认为它将继续处理新创建的

子线程。由于我的班级与控件无关,因此我没有访问InvokeRequired或Invoke的
。有没有办法确保我的

子线程真的完整?


-BKN

I have an object that starts a thread to do a "process". One of the steps
inside this thread launches 12 other threads via a Delegate.BeginInvoke to
process. After these 12 threads are launched, the main thread waits. At the
completion of each subthread, the mainthread checks all 12 thread objects to
see if they are done. If they are, raise an event that says we''re done.

So, it''s kinda like this:

ProcessThread
- Creates a ProcessObject
- ProcessObject Execute creates a list of 12 SubProcessObjects
- Invokes 12 new SubProcessThreads
- SubProcessObject executes
- SubProcessObject sets a "Completed" flag
- The end routine checks the SubProcessObject list to see if all
"Completed" flags
- If so, raise event to main process to continue to next ProcessObject

Problem is, I don''t think the pick-up-on-main-thread is really executing on
the main thread. I think it''s continuing to process on the newly created
subthread. Since my class has nothing to do with a Control, I don''t have
access to InvokeRequired or Invoke. Is there a way ot make sure my
subthreads really complete?

-BKN

推荐答案

使用Delegate.BeginInvoke称为异步委托。使用

异步委托使用线程池中的线程。除非所有12个委托调用都处于活动状态(即,当其他

代表被调用时它们尚未完成),它很可能是一个异步委托是
重用另一个异步委托使用的线程池线程。


如果你想通过Thread对象跟踪线程,那么你就不要我想要

来使用线程池线程。


你如何跟踪每个线程?


通常情况下,如果一个线程的延续依赖于一个或多个其他线程,你可以为每个线程对象调用Thread.Join() -

你可以'与线程池线程有关。


-
http://www.peterRitchie.com/

" Bryce K. Nielsen"写道:
Using Delegate.BeginInvoke is called "Asynchronous Delegates". Using
asynchronous delegates uses threads from the thread pool. Unless all 12
delegate calls are active (i.e. they haven''t completed by the time the other
delegates are called) it''s more than likely an asynchronous delegate is
reusing a thread pool thread that was uses by another asynchronous delegate.

If you want to keep track of threads via a Thread object then you don''t want
to use thread pool threads.

How are you keeping track of each thread?

Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread object--something
you can''t do with thread pool threads.

--
http://www.peterRitchie.com/
"Bryce K. Nielsen" wrote:
我有一个对象启动一个线程来做一个进程。这个线程中的一个步骤是通过Delegate.BeginInvoke启动12个其他线程来进行处理。启动这12个线程后,主线程等待。在每个子线程完成后,mainthread检查所有12个线程对象,看看它们是否完成。如果是的话,举起一个说我们已经完成的事件。

所以,它有点像这样:

ProcessThread
- 创建一个ProcessObject
- ProcessObject Execute创建一个包含12个SubProcessObjects的列表
- 调用12个新的SubProcessThreads
- SubProcessObject执行
- SubProcessObject设置一个Completed - flag
- 结束例程检查SubProcessObject列表以查看是否所有
已完成。标志
- 如果是这样,将事件提升到主进程继续到下一个ProcessObject

问题是,我不认为主要线程的接收正在执行
主线程。我认为它将继续处理新创建的
子线程。由于我的课程与控件无关,因此我无法访问InvokeRequired或Invoke。有没有办法确保我的
子线程真的完整?

-BKN
I have an object that starts a thread to do a "process". One of the steps
inside this thread launches 12 other threads via a Delegate.BeginInvoke to
process. After these 12 threads are launched, the main thread waits. At the
completion of each subthread, the mainthread checks all 12 thread objects to
see if they are done. If they are, raise an event that says we''re done.

So, it''s kinda like this:

ProcessThread
- Creates a ProcessObject
- ProcessObject Execute creates a list of 12 SubProcessObjects
- Invokes 12 new SubProcessThreads
- SubProcessObject executes
- SubProcessObject sets a "Completed" flag
- The end routine checks the SubProcessObject list to see if all
"Completed" flags
- If so, raise event to main process to continue to next ProcessObject

Problem is, I don''t think the pick-up-on-main-thread is really executing on
the main thread. I think it''s continuing to process on the newly created
subthread. Since my class has nothing to do with a Control, I don''t have
access to InvokeRequired or Invoke. Is there a way ot make sure my
subthreads really complete?

-BKN



> ;你如何跟踪每个线程?
> How are you keeping track of each thread?


主进程有一个与每个

线程/委托相关联的对象列表。在这个对象中是一个在进程结束时设置的标志,然后

然后来自主进程的AsyncCallback检查进程列表为

看看他们是否是全部完成。如果是,继续处理,否则不要等待,直到另一个完成线程再次调用它。

通常,如果一个线程的延续是依赖的在一个或多个其他线程上,你会为每个线程
对象调用Thread.Join() - 你不能用线程池线程做什么。

The main process has a list of objects that are associated with each
thread/delegate. In this object is a flag set at the end of the process, and
then the AsyncCallback from the main process checks the list of processes to
see if they''re all completed. If they are, continue processing, otherwise do
nothing and wait until it''s called again by another completing thread.
Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread
object--something
you can''t do with thread pool threads.




好​​吧,之前我在Form上执行了所有代码,所以在

结束时(在调用AsyncCallback并且所有objects.Completed标志为

true)我会调用Form.Invoke,这将继续处理

原始/表格线程。但是,我最近将主要过程

从Form拆分到它自己的Thread对象上。因此,由于此对象不是

Control,因此它没有Invoke()方法。所以我担心最后,

进程会在最后执行的线程上运行,而不是将控制权返回给主进程线程。


所以Thread.Join()会允许我在主线程上选择备份吗?


-BKN



Well, previously I had all my code on the Form executing stuff, so at the
end (after the AsyncCallback was called and all objects.Completed flag was
true) I would call Form.Invoke and this would continue processing back on
the original/Form thread. However, I recently decoupled the main process
from the Form onto it''s own Thread object. So, since this object is not a
Control, it has no Invoke() method. So I''m afraid that at the end, the
process is picking up on the last-executed thread, instead of giving control
back to the main process thread.

So Thread.Join() would allow me to pick back up on the main thread?

-BKN


一般的经验法则:如果.NET 1.1中存在概念/方法,则使用后台线程调用

回调/事件处理程序。这是异步委托的情况,他们是使用后台

线程调用的,而不是调用委托的线程。


在.NET 2.0中,你可以使用AsyncOperationManager类来确保使用特定线程调用异步

回调。


即使你打电话您在主要上的AsyncCallback线程,你还在继续

处于这样一种情况:启动回调的线程仍然是在调用回调时技术上运行的
。在异步的情况下

委托此回调意味着该方法已完成执行;它没有
意味着线程已经完成执行。


知道线程是否已终止(没有轮询)的唯一方法是,如果你

使用Thread.Join,这是你不能用于线程池线程的东西。在

你的情况下,我不知道为什么你要区分

任务何时完成以及线程何时终止.. 。


我应该指出的另一件事是何时使用多个线程。对于多线程来说,实际上只有三个可靠的场景。一种情况是:

你想要产生一个线程来做工作,因为另一个没有使用大量CPU需要活动的线程。这包括从GUI线程产生

后台线程以保持GUI响应。第二个
场景是你想要利用多处理器或多b $ b多核处理器。第三种情况是你想等待一些东西

来完成(比如异步IO)而不会阻塞另一个线程。


如果你产生了多个线程一个单处理器,单核处理器,b
处理器,然后你实际上放慢了程序的速度。你的程序是现在使用更多的系统资源,要求系统管理你的线程

(它们之间的时间切片,产生上下文切换),并添加

处理启动并等待线程。所有这些都需要处理

时间。


-
http://www.peterRitchie.com/

" Bryce K. Nielsen"写道:
A general rule of thumb: if the concept/method exists in .NET 1.1 then the
callback/event-handler is being called using the background thread. This is
the case for asynchronous delegates, they''re called using the background
thread, not the thread that invoked the delegate.

In .NET 2.0 you can use the AsyncOperationManager class to make sure async
callbacks are called using a particular thread.

Even if you call your AsyncCallback on the "main" thread, you''re still going
to be in a situation where the thread that instigates the callback is still
technically running when the callback is called. In the case of async
delegates this callback means the method has finished executing; it doesn''t
mean the thread has finished executing.

The only way to know if a thread has terminated (without polling) is if you
use Thread.Join, something that you can''t use with thread pool threads. In
your case, I don''t know why you''d want to make the distinction of when the
task is completed and when the thread has terminated...

Another thing I should point out is when to use multiple threads. There''s
really only three reliable scenarios for multiple threads. One scenario is:
you want to spawn a single thread to do work because another thread that does
not use much of the CPU needs to be active. This includes spawning
background threads from a GUI thread to keep the GUI responsive. A second
scenario is if you want to take advantage of multi-processor or
multi-core-processors. The third scenario is you want to wait for something
to complete (like asynchronous IO) without blocking another thread.

If you spawn more than one thread on a single processor, single-core
processor, then you''re actually slowing your program down. Your program is
now using more system resources, asking the system to manage your threads
(time-slicing between them, incurring a context switch), and adding
processing to start and wait for the threads. All of which take processing
time.

--
http://www.peterRitchie.com/
"Bryce K. Nielsen" wrote:
你如何跟踪每个线程?



主进程有一个列表与每个
线程/委托相关联的对象。在此对象中是在进程结束时设置的标志,然后来自主进程的AsyncCallback检查进程列表以查看它们是否全部完成。如果是,继续处理,否则什么都不做,等到另一个完成的线程再次调用它。



The main process has a list of objects that are associated with each
thread/delegate. In this object is a flag set at the end of the process, and
then the AsyncCallback from the main process checks the list of processes to
see if they''re all completed. If they are, continue processing, otherwise do
nothing and wait until it''s called again by another completing thread.

通常,如果一个线程的延续是依赖的在一个或多个其他线程上,你会为每个线程
对象调用Thread.Join() - 你不能用线程池线程做什么。
Normally, if the continuation of one thread is Dependant on one or more
other threads you would call Thread.Join() for each thread
object--something
you can''t do with thread pool threads.

结束时(在调用AsyncCallback之后所有的objects.Completed标志都是
为真)我会打电话Form.Invoke,这将继续处理原始/表单线程。但是,我最近将主要进程从Form拆分到它自己的Thread对象上。因此,由于此对象不是
控件,因此它没有Invoke()方法。所以我担心最后,
进程会在最后执行的线程上进行,而不是将控制权交还给主进程线程。

那么Thread.Join()会允许我选择主线程吗?

-BKN



Well, previously I had all my code on the Form executing stuff, so at the
end (after the AsyncCallback was called and all objects.Completed flag was
true) I would call Form.Invoke and this would continue processing back on
the original/Form thread. However, I recently decoupled the main process
from the Form onto it''s own Thread object. So, since this object is not a
Control, it has no Invoke() method. So I''m afraid that at the end, the
process is picking up on the last-executed thread, instead of giving control
back to the main process thread.

So Thread.Join() would allow me to pick back up on the main thread?

-BKN



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

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