C# net中的任务并行库顺序访问
我正在编写一个显示文件下载状态的组件。有一个应用程序访问我的组件的方法并传递参数,该参数进一步包含我需要在屏幕上显示的信息 因此,服务非常频繁地访问我的方法,因为它需要为我提供大量文件的信息(这些文件当前在下载队列中) 所以这就满足了我的所有需求,到目前为止,我还没有遇到任何实际问题。 但这种方法存在一个潜在的问题。由于这种方法仍在继续被称为,这种情况可能会发生 调用1选项。FileName=“文件1” options.datatransfer=“3 mb” 调用2选项。FileName=“文件2” options.datatransfer=“6 mb” 调用3个选项。FileName=“文件1” options.datatransfer=“6 mb” 等等。每次调用此方法时,都会初始化一个新任务,当任务完成时,它会用信息更新MainUI 问题 无法保证先完成哪项任务。有可能Call3首先完成并显示文件1下载6 mb的信息,然后Call1完成并更新文件1下载3 mb的信息,这绝对是不可接受的 我想保证任务1必须在任务3之前完成,因为这两个任务都获得了文件1的信息C# net中的任务并行库顺序访问,c#,.net,multithreading,task-parallel-library,C#,.net,Multithreading,Task Parallel Library,我正在编写一个显示文件下载状态的组件。有一个应用程序访问我的组件的方法并传递参数,该参数进一步包含我需要在屏幕上显示的信息 因此,服务非常频繁地访问我的方法,因为它需要为我提供大量文件的信息(这些文件当前在下载队列中) 所以这就满足了我的所有需求,到目前为止,我还没有遇到任何实际问题。 但这种方法存在一个潜在的问题。由于这种方法仍在继续被称为,这种情况可能会发生 调用1选项。FileName=“文件1” options.datatransfer=“3 mb” 调用2选项。FileName=“文件
谢谢如果您可以修改服务器并在发送的邮件中添加版本号,则随后可以丢弃版本小于该文件最后接收版本的任何邮件
您还可以在更新数据行之前在客户端上添加版本号,只要消息以正确的顺序到达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());
}
private ConcurrentQueue_tasks=new ConcurrentQueue();
私有void ProcessMessage(MessageOptions选项)
{
var t=Task.Factory.StartNew(()=>
{
//使用选项对象更新数据行
返回选项;
});
_任务排队(t);
任务t1=t.ContinueWith(=>
{
//每次任务完成时,从队列开始更新所有已完成任务的UI
任务优先队列;
while(_tasks.TryPeek(out firstInQueue)&&
firstInQueue.IsCompleted)
{
//此alwys在同一线程中运行。我们可以确保该项目仍在队列中
_tasks.TryDequeue(out firstInQueue);
var taskOptions=firstInQueue.Result;
//下面是更新MainUI的代码
}
}
,TaskScheduler.FromCurrentSynchronizationContext());
}
@svick我在问题中提到,它还没有失败。但是我看不出有任何理由我将来不会失败。任务可以按任何顺序完成,因此可能导致问题。MessageOptions是否只包含一条消息或多条消息?@Slugart一次包含一条消息“有一些windows服务可以访问我的应用程序的方法”-客户端是调用服务器还是以其他方式调用?如果是客户端,这是在什么线程上发生的?@Slugart很抱歉搞混了,我已经更新了这个问题。这看起来像是黑客攻击。即使这次我以某种方式修改了服务器,也不能保证下次我面对这个问题时我能做到。是的,这似乎是可行的。不过我需要测试一下。
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());
}