任务的并行执行嗯,基本上我有一堆任务(10个),我想同时启动所有任务并等待它们完成。完成后我想执行其他任务。我阅读了很多关于此的资源,但我无法针对我的具体情况做好准备......这是我到目前为止所拥有的(代码简化):publicasyncTaskRunTasks(){vartasks=newList{newTask(async()=>awaitDoWork()),//以此类推其他9个类似的任务}Parallel.ForEach(tasks,task=>{task.Start();});任务。WhenAll(任务)。ContinueWith(done=>{//运行其他任务});}//这个函数执行一些I/O操作publicasyncTaskDoWork(){varresults=awaitGetDataFromDatabaseAsync();foreach(varresultinresults){awaitReadFromNetwork(result.Url);所以我的问题是当我在等待任务完成时使用WhenAll调用时,它告诉我所有任务都已完成,即使它们都没有完成。我尝试在我的foreach中添加Console.WriteLine,当我进入延续任务时,数据不断从我之前没有完成的任务中传入。我在这里做错了什么?您几乎不应该直接使用Task构造函数。在您的情况下,该任务只会触发您迫不及待的实际任务。您只需调用DoWork并获取任务,将它们存储在列表中并等待所有任务完成。含义:tasks.Add(DoWork());//...awaitTask.WhenAll(任务);但是,异步方法会同步运行,直到达到第一个等待未完成任务为止。如果您担心该部分花费的时间太长,请使用Task.Run将其卸载到另一个ThreadPool线程,然后将任务存储在列表中:tasks.Add(Task.Run(()=>DoWork()));//...awaitTask.WhenAll(任务);基本上你混合了两个不兼容的异步范例;即Parallel.ForEach()和异步等待。为了你想要的,做一个或另一个。例如,您可以使用Parallel.For[Each]()并完全删除async-await。Parallel.For[Each]()只会在所有并行任务完成时返回,然后您可以继续执行其他任务。该代码还有一些其他问题:如果您希望使用TPL在不同线程中并行运行这些任务,您可能需要这样的东西:publicasyncTaskRunTasks(){vartasks=newList>{DoWork,//...};awaitTask.WhenAll(tasks.AsParallel().Select(asynctask=>awaittask()));//运行其他任务}这些方法只并行化少量代码:将方法排队到线程池并返回已完成的任务。此外,对于如此少量的任务,并行化可能比仅异步运行花费更多时间。这只有在您的任务在第一次等待之前进行更长时间(同步)工作时才有意义。对于大多数情况,更好的方法是:publicasyncTaskRunTasks(){awaitTask.WhenAll(new[]{DoWork(),//...});//Runtheothertasks}我的意见是在你的代码中:在将代码传递给Parallel.ForEach之前,你不应该将代码包装在任务中。您可以等待Task.WhenAll而不是使用ContinueWith。DoWork方法是一种异步I/O方法。这意味着您不需要多个线程来执行其中的几个,因为大多数时候该方法将异步等待I/O完成。一个线程就足以做到这一点。publicasyncTaskRunTasks(){vartasks=newList{DoWork(),//以此类推其他9个类似的任务};等待Task.WhenAll(任务);//Runtheothertasks}你几乎不应该使用任务构造函数来创建新任务。要创建异步I/O任务,只需调用async方法即可。要创建要在线程池线程上执行的任务,请使用Task.Run。您可以阅读这篇文章,详细了解Task.Run和创建任务的其他选项。还要在Task.WhenAll周围添加一个try-catch块注意:抛出一个System.AggregateException实例,它充当一个或多个已发生异常的包装器。这对于协调多个任务的方法(例如Task.WaitAll()和Task.WaitAny())很重要,因此AggregateException能够包含运行任务中发生的所有异常。以上就是《C#学习教程:任务分担的并行执行》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望你多多关注——试试{Task.WaitAll(tasks.ToArray());}catch(AggregateExceptionex){foreach(Exceptioninnerinex.InnerExceptions){Console.WriteLine(String.Format("Exceptiontype{0}from{1}",inner.GetType(),inner.Source));}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
