繁体   English   中英

连续链接任务,然后运行并行任务

[英]Chaining tasks with continuation and run parallel task afterward

并行任务的工作流程

http://i.stack.imgur.com/luRnu.png

我希望能在遇到的问题上获得帮助。 因此,问题在于我正在运行并行任务以在文件夹中搜索文件。 每个任务都需要标识文件并将其添加到文件数组中。 接下来,等待每个任务完成,以便收集文件,然后对结果进行排序。 接下来,通过对每个文件运行一个任务以读取该文件来获取匹配的模式,从而独立处理已排序的文件。 最后阶段是将所有结果汇总为易于阅读的格式,并以用户友好的方式进行显示。

所以问题是我想以一种不会阻塞UI线程的适当方式链接任务。 我希望能够在程序处于任何阶段的情况下取消所有操作。

把它们加起来:

阶段1:通过搜索文件夹来查找文件。 每个任务通过文件夹树进行递归搜索。

阶段2:对找到的所有文件进行排序并清理重复项

阶段3:启动新任务以独立处理文件。 每个任务都会打开一个文件并搜索匹配的模式。

第4阶段:将每次单个文件搜索的结果汇总到一个庞大的结果集中,使其易于阅读。

     List<Task> myTasks = new List<Task>();

// ==== stage 1 ======
        for(int i = 0; i < 10; i++) {
           string directoryName = directories[i];

           Task t = new Task(() =>
           {
              FindFiles(directoryName);
           });

           myTasks.Add(t);
            t.Start();
        }

// ==== stage 2 ====
        Task sortTask = Task.Factory.ContinueWhenAll(myTasks.ToArray(), (t) =>
        {
           if(_fileResults.Count > 1) {
              // sort the files and remove any duplicates
           }
        });

        sortTask.Wait();

// ==== stage 3 ====
        Task tt = new Task(() =>
        {
             Parallel.For(0, _fileResults.Count, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = token, TaskScheduler = _taskScheduler },
                    (i, loopstate) => {
              // 1. open file
              // 2. read file
              // 3. read file line by line
              }
        }

// == stage 4 === 
        tt.ContinueWith((t) =>
        {
           // 1. aggregate the file results into one giant result set
           // 2. display the giant result set in human readable format
        }, token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext());

      tt.start();

不要同步等待任何任务完成。 如果在先前创建的任务之后需要执行任何这些操作,请添加该工作作为该任务的延续。

您是否考虑过使用async/await功能-根据您的问题,它完全满足您的需求。 这是使用它的快速尝试:

try
{
    List<Task<File[]>> stage1Tasks = new List<Task<File[]>>();

    // ==== stage 1 ======
    for (int i = 0; i < 10; i++)
    {
        string directoryName = directories[i];

        Task<File[]> t = Task.Run(() =>
        {
            return FindFiles(directoryName);
        },
            token);

        stage1Tasks.Add(t);
    }

    File[][] files = await Task.WhenAll(stage1Tasks).ConfigureAwait(false);

    // Flatten files.
    File[] _fileResults = files.SelectMany(x => x).ToArray();

    // ==== stage 2 ====
    Task<File[]> sortFilesTask = Task.Run(() =>
    {
        if (_fileResults.Count > 1)
        {
            // sort the files and remove any duplicates
            return _fileResults.Reverse().ToArray();
        }
    },
        token);

    File[] _sortedFileResults = await sortFilesTask.ConfigureAwait(false);

    // ==== stage 3 ====
    Task<SomeResult[]> tt = Task.Run(() =>
    {
        SomeResult[] results = new SomeResult[_sortedFileResults.Length];
        Parallel.ForEach(_sortedFileResults,
            new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount,
                CancellationToken = token,
                TaskScheduler = _taskScheduler
            },
            (i, loopstate) =>
            {
                // 1. open file
                // 2. read file
                // 3. read file line by line
                results[i] = new SomeResult( /* here goes your results for each file */);
            });
        return results;
    },
        token);

    SomeResult[] theResults = await tt.ConfigureAwait(false);


    // == stage 4 === 
    // 1. aggregate the file results into one giant result set
    // 2. display the giant result set in human readable format
    // ....

}
catch (TaskCanceledException)
{
    // some task has been cancelled...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM