我跟着this tutorial創建一個優先級隊列,並用阻塞集合包裝它。我有一個DataGrid,它連接到發出變化事件的基礎優先級隊列。我可以通過UI線程將項目添加到集合中,並且可以阻止緩衝區滿足其應有的時間。BlockingCollection + UI線程
現在我該如何消耗這些物品?下面是我有:
public DownloadViewModel()
{
Queue = new ConcurrentPriorityQueue<DownloadItem>(10);
Buffer = new BlockingCollection<KeyValuePair<int, DownloadItem>>(Queue, 10000);
Task.Factory.StartNew(() =>
{
KeyValuePair<int, DownloadItem> item;
while(!Buffer.IsCompleted)
{
if(Buffer.TryTake(out item))
{
// do something with the item
}
Thread.SpinWait(100000);
}
});
}
但只要我添加了Task.Factory.StartNew
位,我的應用程序突然需要30秒出現的窗口前(之前它是瞬發),當我做添加一個項目,我得到例外
此類CollectionView不支持從與分派器線程不同的線程更改其SourceCollection。
我明白了,但是真的需要使用UI線程來獲取項目嗎?這並不能擊敗使用此BlockingCollection的整個目的嗎?我想創建4個或8個消費者並讓他們並行運行。
這應該怎麼做?
它真的非常有必要只從UI線程更新UI控件。這是例外情況告訴你的。是的,這很快就會破壞精心製作的線程方案的實用性。 – 2010-10-19 20:12:26
@Hans:當然,但是當阻塞隊列嘗試接收一個項目時,底層隊列會發出更改通知,..爲什麼不能自動將其委派回UI線程?消費者爲什麼要被阻止?無論如何,我願意接受任何sol'n現在,即使它的效率比我認爲應該低一點。我想這是一個很常見的範例。生產者 - 消費者不是什麼新鮮事,向用戶顯示剩餘物品應該不那麼困難? – mpen 2010-10-19 20:28:34
談到穿線時,沒有什麼是自動的或簡單的。將結果收集到列表中,並使用Dispatcher.BeginInvoke更新UI。 – 2010-10-19 20:38:46