我有一个函数,该函数将同时由5个线程处理,但会传递不同的参数。我想等待使主线程等待其余线程,然后释放它。我什至不确定CancellationToken
是否可以与Threadpool一起使用,因为所有示例都与Tasks一起使用,并且我想设置一个按钮以在某个时刻停止线程。
我知道有很多关于线程的信息,但这是实际的问题。我不知道哪个线程类更好或者如何实现它们,因为存在歧义的示例。一位消息人士说,应该以一种方式完成,而以另一种方式完成。这是我看到的一些示例。您可以看到,与其他2个链接相比,MSDN的示例是模棱两可的,或者至少我没有提到这一点。 https://jeremylindsayni.wordpress.com/2016/03/26/how-to-use-manualresetevent-in-c-to-block-one-thread-until-another-has-completed/,How to make main thread to wait until other threads ends和https://docs.microsoft.com/en-us/dotnet/api/system.threading.manualresetevent?view=netframework-4.7.2。
private void DoJob(object state)
{
Console.WriteLine("Delaying...");
Thread.Sleep(3000);
Console.WriteLine("Thread done");
_manualResetEvent.Set();
}
// on some button click event
_manualResetEvent = new ManualResetEvent(false);
for (int i = 0; i < threadsNumericUpDown.Value; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoJob), i);
}
_manualResetEvent.WaitOne();
Console.WriteLine("Main thread released");
在上面的示例中,我想让主线程等待其余线程,直到它们完成,但是在第一个线程完成之后主线程将被释放。
Delaying...
Delaying...
Delaying...
Delaying...
Thread done
Main thread released
Thread done
Thread done
Thread done
如果我将WaitOne
放入每个线程(DoJob方法)中,并将Set
放入当前的WaitOne位置,则首先释放主线程,而我想要的是在所有其他线程之后释放它完成。
答案 0 :(得分:2)
就您而言,您实际上只是使用任务:
var tasks = new List<Task>();
for (int i = 0; i < threadsNumericUpDown.Value; i++)
{
tasks.Add(Task.Run(() => DoJob(i)));
}
Task.WaitAll(tasks);
如果由于某种原因您不想使用任务,可以看看CountdownEvent
,它专门用于等待一定数量的异步操作:
private void DoJob(object state)
{
Console.WriteLine("Delaying...");
Thread.Sleep(3000);
Console.WriteLine("Thread done");
_countdownEvent.Signal();
}
// on some button click event
_countdownEvent = new CountdownEvent(threadsNumericUpDown.Value);
for (int i = 0; i < threadsNumericUpDown.Value; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoJob), i);
}
_countdownEvent.Wait();
Console.WriteLine("Main thread released");