C#锁定和队列上的多线程

Jor*_*dan 2 c# concurrency multithreading locking

我正在编写一个多线程应用程序,我担心2个线程访问队列

线程1将项放入队列中进行处理线程2从队列中删除要处理的项

线程1每分钟运行一次,因为它正在拉动数据的性质.线程2始终在运行,它从队列中删除一个项目并休眠100毫秒.我必须这样做,以确保我不会淹没它在项目出列时调用的服务.

我假设在添加或删除项目时,两个线程都应该锁定队列.有进一步的考虑吗?例如,假设线程1有一个锁,而线程2试图访问它.一旦锁被删除,线程2是否只知道等待并恢复?

是否最好使用ConcurrentQueue和TryDequeue,如果它失败,那么只需要100毫秒的睡眠时间?

提前致谢

x0n*_*x0n 8

如果你BlockingCollection<T>像我在NuGet的VS控制台调度程序中那样使用我的PostKey/WaitKey实现,那就更容易了.消耗线程调用Take(...)将阻塞,直到另一个线程调用Add(...).没有必要进行民意调查.此外,您可能希望将取消令牌传递给该Take方法,以便另一个线程可以停止使用者线程,如果它当前正在等待Add永远不会到来的那个.以下是相关方法:

private readonly BlockingCollection<VsKeyInfo> _keyBuffer = 
      new BlockingCollection<VsKeyInfo>();
private CancellationTokenSource _cancelWaitKeySource;

// place a key into buffer
public void PostKey(VsKeyInfo key)
{
    if (key == null)
    {
        throw new ArgumentNullException("key");
    }
    _keyBuffer.Add(key);
}

// signal thread waiting on a key to exit Take
public void CancelWaitKey()
{
    if (_isExecutingReadKey && !_cancelWaitKeySource.IsCancellationRequested)
    {
        _cancelWaitKeySource.Cancel();
    }
}

// wait for a key to be placed on buffer
public VsKeyInfo WaitKey()
{
    try
    {
        // raise the StartWaitingKey event on main thread
        RaiseEventSafe(StartWaitingKey);

        // set/reset the cancellation token
        _cancelWaitKeySource = new CancellationTokenSource();
        _isExecutingReadKey = true;

        // blocking call
        VsKeyInfo key = _keyBuffer.Take(_cancelWaitKeySource.Token);

        return key;
    }
    catch (OperationCanceledException)
    {
        return null;
    }
    finally
    {
        _isExecutingReadKey = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅http://nuget.codeplex.com/SourceControl/changeset/view/45e353aca7f4#src%2fVsConsole%2fConsole%2fConsole%2fConsoleDispatcher.cs.