我正在从一个服务器端控制台应用程序接收来自多个WCF服务的数据,做了一些工作,然后通过使用SignalR的单个连接转发结果到IIS服务器。等待消费者使用BlockingCollection作为队列的异步方法
我试图用生产者消费者模式实现这一点,其中WCF服务是生产者,使用SignalR发送数据的类是消费者。对于队列我使用BlockingCollection。
但是,当使用await/async发送消费者while循环中的数据时,直到所有其他线程完成将数据添加到队列为止。
出于测试目的,我用Task.Delay(1000).Wait();
或await Task.Delay(1000);
替代了实际发送数据的代码,两者都被卡住。 一个简单的Thread.Sleep(1000);
似乎工作得很好,导致我认为异步代码是问题。
所以我的问题是:是否有东西阻止在while循环中完成异步代码?我错过了什么?
我开始消费者线程这样的:
new Thread(Worker).Start();
和消费者代码:
private void Worker()
{
while (!_queue.IsCompleted)
{
IMobileMessage msg = null;
try
{
msg = _queue.Take();
}
catch (InvalidOperationException)
{
}
if (msg != null)
{
try
{
Trace.TraceInformation("Sending: {0}", msg.Name);
Thread.Sleep(1000); // <-- works
//Task.Delay(1000).Wait(); // <-- doesn't work
msg.SentTime = DateTime.UtcNow;
Trace.TraceInformation("X sent at {1}: {0}", msg.Name, msg.SentTime);
}
catch (Exception e)
{
TraceException(e);
}
}
}
}
阻止和异步不是朋友。如果你将'async'与'BlockingCollection'混合在一起,你应该强烈考虑抛开'BlockingCollection '并看看TPL Dataflow。 'BufferBlock '是一个很好的起点,大约相当于'BlockingCollection ',但数据流还有更多可供生产者/消费者使用的场景。花点时间来了解它。这很值得。 –
spender
不错,非常感谢,我会研究它。 –