Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 手动重置事件大小检查是否足以等待多个线程?_C#_Multithreading_Manualresetevent - Fatal编程技术网

C# 手动重置事件大小检查是否足以等待多个线程?

C# 手动重置事件大小检查是否足以等待多个线程?,c#,multithreading,manualresetevent,C#,Multithreading,Manualresetevent,我目前正在使用ManualResetEvent,让单个线程等待多个线程向线程管理器的队列中添加内容。如果线程管理器接收到使用手动重置事件的信号,它将使添加的项目出列并进行进一步处理。我唯一的问题是,如果触发了多个集合,则不会处理其他队列项目。(见第B点) while(正在运行) { //答:我的解决方法是检查队列是否有项,如果没有,则等待其他线程设置事件 if(DataQueue.Count 0) { DataQueue.Dequeue(); } //重置事件以避免处理器阻塞 ResetEven

我目前正在使用ManualResetEvent,让单个线程等待多个线程向线程管理器的队列中添加内容。如果线程管理器接收到使用手动重置事件的信号,它将使添加的项目出列并进行进一步处理。我唯一的问题是,如果触发了多个集合,则不会处理其他队列项目。(见第B点)

while(正在运行)
{
//答:我的解决方法是检查队列是否有项,如果没有,则等待其他线程设置事件
if(DataQueue.Count 0)
{
DataQueue.Dequeue();
}
//重置事件以避免处理器阻塞
ResetEvent.Reset();
}
我在这里的解决方法是在点a上添加队列大小条件。 是否有其他方法来执行此操作以避免死锁


注意:关于ManualResetEvent的使用示例中给出的通常情况是,单个线程上的事件有多个线程等待(ManualResetEvent.Wait),但此处多个线程触发(ManualResetEvent.Set)该事件。是否有其他类用于此场景?

您可以处理队列中的所有项目(如果有),然后等待事件发出信号

当事件发出信号时,立即将其重置

若在处理完队列中的最后一个项目后发出事件信号,最糟糕的情况是您将检查队列,队列将为空

while (IsThreadRunning)
{
  while ( DataQueue.Count > 0 )
  {
    DataQueue.Dequeue();
  }
  ResetEvent.WaitOne();
  ResetEvent.Reset();
}

立即转储手动重置事件。不要为此使用任何类型的事件。使用信号灯和锁。在push方法中,锁定队列,将对象推到队列上,退出lock语句块,然后向信号量发送信号。在pop方法中,等待信号量,然后锁定队列,弹出对象并退出lock语句块


这是如果你真的想自制生产者消费者队列。如果您想要一个已经工作的队列,请查看BlockingCollection类。

为什么不简单地将第二个If改为while?@Nap-否。使用队列锁和信号量(如果队列有界,则使用两个信号量)是实现生产者-消费者队列的“计算机科学101”方法。我不知道开发人员从哪里得到了使用事件而不是信号量的想法,他们迫切需要一个带有计数器的同步机制!
while (IsThreadRunning)
{
  while ( DataQueue.Count > 0 )
  {
    DataQueue.Dequeue();
  }
  ResetEvent.WaitOne();
  ResetEvent.Reset();
}