在继续之前如何等待线程完成?
时间:2020-03-05 18:38:46 来源:igfitidea点击:
我有一些代码可以在.NET CF 2.0上启动线程:
ThreadStart tStart = new ThreadStart(MyMethod); Thread t = new Thread(tStart); t.Start();
如果我在循环中调用它,则项目将不按顺序完成。如何在t.Start()之后引入等待,以便线程的工作在代码继续之前完成?比手动创建线程,BeginInvoke / EndInvoke会是更好的选择吗?
解决方案
回答
如果我正确地阅读了这篇文章,那么我们正在启动一堆线程上的工作项,但是我们担心这些线程会无序地完成工作,并且宁愿等到每个线程按照它们的启动顺序来完成工作?
如果是这种情况,那么我不确定为什么要为每个工作项创建一个线程。也许你可以扩大?
如果确实需要等待线程完成,则可以执行以下操作:
t.Join();
回答
我们需要在线程上施加多少顺序?如果我们只需要在循环中开始的所有工作在代码继续之前完成,但是我们不关心循环中工作的完成顺序,那么调用Join是答案。要在Kevin Kenny的答案中添加更多细节,我们应该在循环外调用Join。这意味着我们将需要一个集合来保存对我们启动的线程的引用:
// Start all of the threads. List<Thread> startedThreads = new List<Thread>(); foreach (...) { Thread thread = new Thread(new ThreadStart(MyMethod)); thread.Start(); startedThreads.Add(thread); } // Wait for all of the threads to finish. foreach (Thread thread in startedThreads) { thread.Join(); }
相反,如果在循环内调用Join,则结果基本上与完全不使用线程相同。循环主体的每次迭代都会创建并启动一个线程,但随后立即将其加入并等待其完成。
如果各个线程产生某种结果(例如,在日志中写一条消息),则消息可能仍会出现乱序,因为线程之间没有协调。通过与Monitor协调,可以使线程按顺序输出结果。
回答
等待线程完成的另一种方法是使用AutoResetEvent。
private readonly AutoResetEvent mWaitForThread = new AutoResetEvent(false); private void Blah() { ThreadStart tStart = new ThreadStart(MyMethod); Thread t = new Thread(tStart); t.Start(); //... (any other things) mWaitForThread.WaitOne(); } private void MyMethod() { //... (execute any other action) mWaitForThread.Set(); }