我一直在使用AutoResetEvent在线程之间进行同步。
但是只有一个等待线程(A-F)被解除阻塞。 - 当线程(X)完成它的工作时,如何让它们全部解锁?
我想我正在使用错误的同步原语 - 我应该使用什么以及如何使用?
代码示例是理想的
答案 0 :(得分:4)
答案 1 :(得分:3)
假设您有以下代码:
class Program
{
static void Main(string[] args)
{
var are = new AutoResetEvent(false);
for (int i = 0; i < 10; i++)
{
var j = i;
new Thread(() =>
{
Console.WriteLine("Started {0}", j);
are.WaitOne();
Console.WriteLine("Continued {0}", j);
}).Start();
}
are.Set();
Console.ReadLine();
}
}
然后你会得到这样的输出:
Started 0
Started 1
Started 2
Started 3
Started 4
Started 5
Started 6
Started 7
Started 8
Continued 0
Started 9
但是如果您改为使用ManualResetEvent
:
class Program
{
static void Main(string[] args)
{
var mre = new ManualResetEvent(false);
for (int i = 0; i < 10; i++)
{
var j = i;
new Thread(() =>
{
Console.WriteLine("Started {0}", j);
mre.WaitOne();
Console.WriteLine("Continued {0}", j);
}).Start();
}
mre.Set();
Console.ReadLine();
}
}
然后你会得到我猜的预期行为:
Started 0
Started 1
Started 2
Started 3
Started 4
Started 5
Started 6
Started 7
Started 8
Started 9
Continued 1
Continued 8
Continued 7
Continued 4
Continued 5
Continued 6
Continued 3
Continued 0
Continued 9
Continued 2
当然,顾名思义,ManualResetEvent
需要手动重置,而AutoResetEvent
自动在第一个{{1>后重置已释放其线程。
答案 2 :(得分:0)
使用System.Threading.ManualResetEvent。
线程A-F调用mre.WaitOne()
以等待线程(X)。
当线程X完成时,调用mre.Set()
将唤醒线程A-F。
在主题X中,通过执行mre.Reset()
将您的mre重置为基本状态。