【发布时间】:2014-08-31 15:28:57
【问题描述】:
这两个代码块在查看控制台时是否具有相同的效果?
请注意:目前我仍在使用并绑定到 .NET 3.5。
第一:
for(int i = 0; i<3;i++)
{
Console.WriteLine(i);
}
第二:
class Worker
{
static int i = 0;
static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
static Object locky = new Object();
static void Work(Object workItem)
{
WaitHandle[] wait = new [] { manualResetEvent };
while (WaitHandle.WaitAny(wait))
{
lock (locky)
{
Console.WriteLine(i++);
}
}
}
}
// main:
Thread thread = new Thread(Worker.Work);
thread.Start();
for (int i=0;i<3;i++)
{
Worker.manualResetEvent.Set();
}
waitHandle 会随着每个信号的增加而增加吗?循环会一直运行到所有信号都完成吗? 或者当线程已经在工作时会忽略信号吗?
有人可以为这件事带来一些启示吗?
【问题讨论】:
-
第二个代码甚至不会编译,所以不,它们没有相同的效果。一旦你得到了可以编译的代码,我建议你自己尝试一下——如果你能看到不同之处,显然有很大的不同。如果你不能,那么这是一个更合理的问题(因为它可能是一个细微的差别)。
-
ManualResetEvent,顾名思义,需要手动重置。它将一直设置到您Reset它 - 因此您将获得无限循环的写入行。此外,您不能锁定值类型!无论如何,请尝试使用可用的最高级别抽象。您似乎对多线程和同步的了解太低了 - 请查看 TPL、DataFlow 和类似的更友好的构造。 -
@Luaan 谢谢你正是我所缺少的。
-
更正了原生类型的锁
-
其实,如果你想走这条路,你真的需要学习更多。例如,
ManualResetEvent(和AutoResetEvent)不是互斥体——更多等待事件的工作线程将获得相同的信号。并且ManualResetEvent.Set是非阻塞的 - 所以你最终可能会遇到这样的情况:你已经设法调用Set三次之前工作线程甚至注意到一次。总而言之,Semaphore可能更适合您的用例。
标签: c# multithreading asynchronous threadpool waithandle