如何等待线程完成工作 [英] How to wait for a thread to finish its work

查看:83
本文介绍了如何等待线程完成工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制台应用程序.一个类(例如,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).

替代方法是:

  1. 在完成所有工作的Worker类中具有WaitHandle,可能是ManualResetEvent,并在其上调用WaitOne.

  1. Have a WaitHandle, probably a ManualResetEvent, in the Worker class which is Set when it completes all its work, and call WaitOne 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屋!

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