C# 有时我也会处理!跳过线程

C# 有时我也会处理!跳过线程,c#,multithreading,event-wait-handle,C#,Multithreading,Event Wait Handle,我使用的是VS 2012、.Net 4.5 执行此代码(只需升级关于线程的文章中的一些示例): 我调试了几次,但通常(并非总是)得到错误的结果。首先(一次或多次)纠正: Avait...10 Avait...11 Got a signal 11 Got a signal 10 但它只是开始跳过一个线程(有时是第一个,有时是第二个): 程序就是不反应。几分钟后,它给出了一些正确的结果,但随后又出现错误 此外,当我一步一步地调试它时,它总是正确运行 那么,也许我应该选择另一种方法?但这看起来像我所

我使用的是VS 2012、.Net 4.5

执行此代码(只需升级关于线程的文章中的一些示例):

我调试了几次,但通常(并非总是)得到错误的结果。首先(一次或多次)纠正:

Avait...10
Avait...11
Got a signal 11
Got a signal 10
但它只是开始跳过一个线程(有时是第一个,有时是第二个):

程序就是不反应。几分钟后,它给出了一些正确的结果,但随后又出现错误

此外,当我一步一步地调试它时,它总是正确运行


那么,也许我应该选择另一种方法?但这看起来像我所期望的,即使线程以随机顺序获得信号…

我很不确定您是否可以对多个唤醒程序使用相同的
AutoResetEvent
,因为它不会等待第一个线程完成其
等待

无法保证每次调用Set方法都会从重置模式为EventResetMode.AutoReset的EventWaitHandle释放线程。如果两个调用靠得太近,以至于第二个调用发生在释放线程之前,则只释放一个线程。就好像第二次呼叫没有发生一样。此外,如果在没有线程等待且EventWaitHandle已发出信号的情况下调用Set,则调用无效

我会在设置信号期间使用
ManualResetEvent
和同步(以确保等待线程接收信号),或者(更好)为每个等待功能使用专用事件(每个线程都会从它自己要等待的事件开始,您需要为这些线程创建一种管理器来创建等待事件,并让
设置
方法来通知所有这些事件)


p、 美国:可以用俄语重复上述内容。顺便说一句,两个线程都会启动并运行,直到它们阻塞WaitHandle。设置WaitHandle时,一个线程将唤醒,事件将重置

您无法保证哪个线程将被唤醒,因此无法确保顺序。正确运行时,10或11将被唤醒,然后是另一个

在应用程序挂起的情况下,问题在于执行顺序。在第一个线程唤醒之前,主线程正在执行对Event.Set()的两个调用。AutoResetEvent不是计数器,它是Set或unset,因此对Set()的第二个调用将丢失

如果在对Set()的调用之间执行Sleep(),则会让其他线程有时间唤醒并重置事件


在它正常工作的情况下,您很幸运,等待的线程有机会在对Set()的调用之间运行。这被称为竞争条件。

非常肯定您是对的。我在wh.Set()之间添加了Thread.Sleep(1000)-呼叫和bug不会重复。ааааааааааааа,аааааа。
Avait...10
Avait...11
Got a signal 11
Got a signal 10
Avait...10
Avait...11
Got a signal 11 (or 10)