.NET 中的任务并行库顺序访问
本文关键字:顺序 访问 并行 任务 NET | 更新日期: 2023-09-27 18:32:20
我正在编写一个显示文件下载状态的组件。有一个应用程序可以访问我的组件的方法并传递参数,该参数进一步包含我需要在屏幕上显示的信息。
因此,服务非常频繁地访问我的方法,因为它需要为我提供大量文件(当前在下载队列中)的信息
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 个选项。文件名="文件 1" 选项。数据传输="3 mb"
调用 2 个选项。文件名="文件 2" 选项。数据传输="6 mb"
调用 3 个选项。文件名="文件 1" 选项。数据传输="6 mb"
等等。每次调用此方法时,都会初始化一个新任务,当任务完成时,它会使用信息更新 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());
}