[英]Task Parallel Library sequential access in .net
我正在編寫一個顯示文件下載狀態的組件。 有一個應用程序可以訪問我的組件的方法並傳遞參數,該參數進一步包含我需要在屏幕上顯示的信息。
因此該服務非常頻繁地訪問我的方法,因為它需要向我提供很多文件的信息(當前正在下載隊列中)
private void ProcessMessage(MessageOptions options)
{
Task t= Task.Factory.StartNew(()=>
{
//update data row using options object
});
Task t1 = t.ContinueWith((continution) =>
{
//here goes the code to update the MainUI
}
,TaskScheduler.FromCurrentSynchronizationContext());
}
因此,這可以滿足我的所有需求,到目前為止,使用這種方法我還沒有遇到任何實際問題。 但是這種方法存在潛在的問題。 隨着這種方法的繼續被稱為這種事情可能發生
調用1選項。FileName=“文件1”選項。DataTransferred=“ 3 mb”
調用2個選項。FileName=“文件2”選項。DataTransferred=“ 6 mb”
調用3個選項。FileName=“文件1”選項。DataTransferred=“ 6 mb”
等等。 每次調用此方法時,都會初始化一個新的Task,並在任務完成時使用信息更新MainUI。
問題
無法保證哪個任務將首先完成。 Call3可能首先完成並顯示文件1下載6 mb的信息,然后Call1完成並更新文件1下載信息3 mb,這絕對是不可接受的。
我想確保任務1必須在任務3之前完成,因為這兩個任務都獲得了文件1的信息。
謝謝
如果可以修改服務器並在發送的消息中添加版本號,則可以隨后丟棄任何版本小於該文件收到的最后一個最新版本的消息。
您還可以在客戶端上添加版本號,然后再更新數據行,只要消息以正確的順序到達ProcessMessage即可。
如果我正確理解了您的問題,則希望您的任務獨立運行,但是無論任務何時完成,都希望繼續執行順序。
我將使用這樣的並發隊列:
private ConcurrentQueue<Task<MessageOptions>> _tasks = new ConcurrentQueue<Task<MessageOptions>>();
private void ProcessMessage(MessageOptions options)
{
var t= Task<MessageOptions>.Factory.StartNew(()=>
{
//update data row using options object
return options;
});
_tasks.Enqueue(t);
Task t1 = t.ContinueWith(_ =>
{
// everytime a task finishes, update the UI for all completed tasks from the start of the queue
Task<MessageOptions> firstInQueue;
while (_tasks.TryPeek(out firstInQueue) &&
firstInQueue.IsCompleted)
{
// this alwys runs in the same thread we can be sure the item is still in the queue
_tasks.TryDequeue(out firstInQueue);
var taskOptions = firstInQueue.Result;
//here goes the code to update the MainUI
}
}
,TaskScheduler.FromCurrentSynchronizationContext());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.