如何等待线程完成工作 [英] How to wait for a thread to finish its work
问题描述
我有一个控制台应用程序.一个类(例如,Worker)在单独的线程中执行一些工作,并在完成时引发事件.但这永远不会发生,因为执行立即结束.我如何等待线程完成并在引发事件后对其进行处理?
I have a console application. A class (let's say Worker) does some work in a separate thread and throws an event when it finishes. But this never happens because the execution ends instantly. How can I wait for the thread to finish and handle the event after it throws?
static void Main(string[] args)
{
Worker worker = new Worker();
worker.WorkCompleted += PostProcess;
worker.DoWork();
}
static void PostProcess(object sender, EventArgs e) { // Cannot see this happening }
编辑:更正了语句的顺序,但这不是问题.
Corrected the order of the statements but that was not the problem.
推荐答案
您有一个竞赛条件,因为这项工作可以在您注册该活动之前完成.为了避免争用情况,请更改代码顺序,以便在开始工作之前注册事件,然后无论完成多快,都将始终引发该事件:
You've got a race condition, in that the work could finish before you register for the event. To avoid the race condition, change the order of the code so you register for the event before starting the work, then it will always be raised, no matter how fast it finishes:
static void Main(string[] args)
{
Worker worker = new Worker();
worker.WorkCompleted += PostProcess;
worker.DoWork();
}
好,问题已被修改,因此您真正要问的是如何等待PostProcess
完成执行.有两种方法可以执行此操作,但是您必须添加更多代码.
OK the question has been modified, so it looks like what you're really asking is how to wait for PostProcess
to finish executing. There are a couple of ways to do this, but you'll have to add some more code.
最简单的方法是,因为事件总是在引发事件的同一线程上执行,所以在Worker
类创建的线程上调用Thread.Join
,例如假定该线程公开为属性:
The easiest way is, because events always execute on the same thread as they are raised, is to call Thread.Join
on the thread the Worker
class creates, e.g. assuming the thread is exposed as a property:
worker.Thread.Join();
(虽然老实说,我可能会保留Thread
的私有性,并在调用它的Worker
类上公开一个名为WaitForCompletion
的方法).
(Although to be honest I'd probably keep the Thread
private and expose a method called something like WaitForCompletion
on the Worker
class that calls it).
替代方法是:
-
在完成所有工作的
Worker
类中具有WaitHandle
,可能是ManualResetEvent
,并在其上调用WaitOne
.
Have a
WaitHandle
, probably aManualResetEvent
, in theWorker
class which isSet
when it completes all its work, and callWaitOne
on it.
在Worker
类中具有一个volatile bool complete
字段,并在循环主体中使用Thread.Sleep
等待它被设置为true
时循环(这可能不是一个好的解决方案,但这是可行的.)
Have a volatile bool complete
field in the Worker
class and loop while waiting for it to be set to true
, using Thread.Sleep
in the loop body (this probably isn't a good solution, but it is feasible).
可能还有其他选择,但这是常见的选择.
There are probably other options too, but that's the common ones.
这篇关于如何等待线程完成工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!