我正在從一個服務器端控制檯應用程序接收來自多個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
不錯,非常感謝,我會研究它。 –