我有一個服務可以確保只有一個彈出窗口同時顯示。 AddPopupAsync
可以同時調用,即彈出是開放的,而另外10個AddPopupAsync
請求順路代碼:如何使使用隊列線程安全的異步方法
public async Task<int> AddPopupAsync(Message message)
{
//[...]
while (popupQueue.Count != 0)
{
await popupQueue.Peek();
}
return await Popup(interaction);
}
但我可以現貨兩個不必要的東西,可以因爲缺乏線程安全的發生:
- 如果隊列爲空,皮克將拋出一個異常
- 如果一個線程A在彈出的第一條語句之前搶佔,另一個線程B不會等待掛起的彈出菜單的自隊列仍然是空的。
Popup方法的工作原理與TaskCompletionSource
,並調用其SetResult
方法之前,popupQueue.Dequeue()
被調用。
我想利用ConcurrentQueue
原子TryPeek
爲了使#1線程安全:
do
{
Task<int> result;
bool success = popupQueue.TryPeek(out result);
if (!success) break;
await result;
}
while (true);
然後我讀到一個AsyncProducerConsumerCollection,但我不知道這是最簡單的解決方案。
我怎樣才能以簡單的方式確保線程安全?謝謝。
我想你已經回答了你自己的問題。 'ConcurrentQueue'有你需要的內置。 –
2014-11-24 12:42:44
您目前的語義是,所有對「AddPopupAsync」的調用都不會完成,直到顯示所有彈出窗口(不只是該特定調用顯示的那個)。你確定這是你想要的語義嗎? – 2014-11-24 12:51:20
@Stephen Cleary由於PopupView和PopupViewModel是單例,每當調用Popup時,模態彈出窗口的狀態都會更改。這就是我使用隊列的原因。 – user4287276 2014-11-24 13:12:07