Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# net中的任务并行库顺序访问_C#_.net_Multithreading_Task Parallel Library - Fatal编程技术网

C# net中的任务并行库顺序访问

C# net中的任务并行库顺序访问,c#,.net,multithreading,task-parallel-library,C#,.net,Multithreading,Task Parallel Library,我正在编写一个显示文件下载状态的组件。有一个应用程序访问我的组件的方法并传递参数,该参数进一步包含我需要在屏幕上显示的信息 因此,服务非常频繁地访问我的方法,因为它需要为我提供大量文件的信息(这些文件当前在下载队列中) 所以这就满足了我的所有需求,到目前为止,我还没有遇到任何实际问题。 但这种方法存在一个潜在的问题。由于这种方法仍在继续被称为,这种情况可能会发生 调用1选项。FileName=“文件1” options.datatransfer=“3 mb” 调用2选项。FileName=“文件

我正在编写一个显示文件下载状态的组件。有一个应用程序访问我的组件的方法并传递参数,该参数进一步包含我需要在屏幕上显示的信息

因此,服务非常频繁地访问我的方法,因为它需要为我提供大量文件的信息(这些文件当前在下载队列中)

所以这就满足了我的所有需求,到目前为止,我还没有遇到任何实际问题。 但这种方法存在一个潜在的问题。由于这种方法仍在继续被称为,这种情况可能会发生

调用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的信息


谢谢

如果您可以修改服务器并在发送的邮件中添加版本号,则随后可以丢弃版本小于该文件最后接收版本的任何邮件


您还可以在更新数据行之前在客户端上添加版本号,只要消息以正确的顺序到达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());
 }