Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.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#_.net_Concurrency_Task - Fatal编程技术网

C# 等待两个同步对象

C# 等待两个同步对象,c#,.net,concurrency,task,C#,.net,Concurrency,Task,我有一个工作线程,它使用AutoResetEvent来确定队列是否已被修改,还有一个CancellationToken来确定队列是否已被取消 ConcurrentQueue queue = new ConcurrentQueue<MyClass>(); static private void Worker() { while (true) { while (queue.Count > 0) { MyCl

我有一个工作线程,它使用AutoResetEvent来确定队列是否已被修改,还有一个CancellationToken来确定队列是否已被取消

ConcurrentQueue queue = new ConcurrentQueue<MyClass>();

static private void Worker()
{
    while (true) 
    {
        while (queue.Count > 0)
        {
            MyClass item;
            if (queue.TryDequeue(out item))
            {
                item.DoWork();
            }
        }
        autoResetEvent.WaitOne(1000);  //Wait for item to be added to queue
        cancellationToken.ThrowIfCancellationRequested();  //Check if cancelled
    }
}
ConcurrentQueue=new ConcurrentQueue();
静态私有void Worker()
{
while(true)
{
而(queue.Count>0)
{
MyClass项目;
if(queue.TryDequeue(out项))
{
项目.道工();
}
}
autoResetEvent.WaitOne(1000);//等待将项添加到队列中
cancellationToken.ThrowIfCancellationRequested();//检查是否已取消
}
}
上面的问题是,对
WaitOne()
的调用将继续阻塞,即使取消令牌已发出信号。在本例中,我有一个1秒的超时,因此主线程将在任务尝试完成并退出之前等待1秒

有没有一种方法可以重写它,以便发出取消令牌的信号将允许工作线程通过
WaitOne()
调用,从而退出?

您可以使用静态方法:

WaitHandle.WaitAny(new[] { autoResetEvent, cancellationToken.WaitHandle }, 1000);
然而,访问有一个缺点:

访问此属性会导致实例化WaitHandle。最好仅在必要时使用此属性,然后尽早处置关联的CancellationTokenSource实例(处置源将处置此分配的句柄)。手柄不应关闭或直接处理


如果您希望有一个方法来获取一个值,该值在添加值之前被阻塞,请使用BlockingCollection,而不是ConcurrentQueue。自己编写这个类毫无意义。您是否可以转换成
新的信号量lim(1,1)
,然后使用
等待(int32,CancellationToken)
?(假设它适合您的需要,并且BlockingCollection并不更适合)