将循环转换为任务

萨沙

我有以下同步代码:

foreach ( var step in result ) {
  step.Run();
}

我试图将其转换为任务,但未成功。我试图Task.WhenAll像这样转换它(并且我确实将异步附加到了方法签名上):

var tasks = new List<Task>();
foreach ( var step in result ) {
    tasks.Add( new Task( () => step.Run() ) );
}
await Task.WhenAll( tasks );

这将立即返回,并且不执行该Run()方法。然后,我尝试将其转换为以下代码:

var tasks = new List<Task>();
foreach ( var step in result ) {
    tasks.Add( new Task( () => step.Run() ) );
}
var task = Task.WhenAll( tasks );
task.Wait();

这永远阻止。但是,当我在循环内创建一个时,它会起作用:

foreach ( var step in result ) {
    var t = Task.Run( () => step.Run() );
    t.Wait();
}

如果我改用await Task.Run( () => step.Run() );它,它将仅等待第一个并恢复主线程。

运行方法如下所示:

public async void Run() {
    var result = Work();
    if ( null != result && result.Count > 0 ) {
        var tasks = new List<Task>();
        foreach ( var step in result ) {
            await Task.Run( () => step.Run() );
        }
    }
}

所有步骤都实现Work()方法(在基类中是抽象的)。我的第一步如下所示:

class NoWorkStep : WorkerStep {
    protected override IList<WorkerStep> Work() {
        Console.WriteLine( "HERE" );
        List<WorkerStep> newList = new List<WorkerStep>();
        for ( int i = 0; i < 10; i++ ) {
            newList.Add( new NoWorkStep2() );
        }
        return newList;
    }
}

我的第二步如下所示:

class NoWorkStep2 : WorkerStep {
    protected override IList<WorkerStep> Work() {
        Console.WriteLine( "HERE-2" );
        return new List<WorkerStep>();
    }
}

我简单地创建一个NoWorkStep实例并调用instance.Run()

在执行步骤时,我在哪里遇到问题Task.WhenAll

编辑:我将Run方法更改为后,调用代码async Task RunAsync

private static async void doIt() {
  var step = new NoWorkStep();
  await step.RunAsync();
}
尤瓦尔·伊察科夫(Yuval Itzchakov)

让我们找出您的代码存在的问题:

new Task(() => step.Run())

这将返回感冒Task,这意味着Task实际上并未启动。为了启动它,您需要致电:

new Task(() => step.Run()).Start)

但是,new Task无论如何都不应该使用,而应该使用Task.Run

如果我改为使用Task.Run(()=> step.Run()); 它仅等待第一个线程并恢复主线程。

这是因为,Run就是async void不能等待。async void仅在顶级事件处理程序中使用,显然这里不是这种情况。

如果要等待所有任务完成,可以执行以下操作:

public async Task RunAsync() 
{
    var result = Work();
    var stepTasks = result.Select(step => Task.Run(() => step.Run()));
    await Task.WhenAll(steps);
}

这将确保所有任务一旦RunAsync完成便已完成执行

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将for循环转换为if

来自分类Dev

将线程转换为任务

来自分类Dev

将问题转换为任务

来自分类Dev

将Rally用户故事转换为任务

来自分类Dev

将Gulp任务转换为Npm的脚本

来自分类Dev

将Rally用户故事转换为任务

来自分类Dev

将DAG转换为任务的巨大延迟

来自分类Dev

将Matlab循环转换为R循环

来自分类Dev

将for循环转换为foreach循环

来自分类Dev

将代码从FOR循环转换为WHILE循环

来自分类Dev

将增强的for循环转换为常规的for循环

来自分类Dev

自动将foreach循环转换为for循环

来自分类Dev

将Stata循环转换为SPSS循环

来自分类Dev

将 For 循环转换为 While 循环(列表)

来自分类Dev

将任务<T>强制转换为任务<DerivedT>

来自分类Dev

将循环语句转换为linq模式

来自分类Dev

将foreach循环转换为linq

来自分类Dev

python:将for循环转换为递归函数

来自分类Dev

将foreach循环转换为LINQ

来自分类Dev

将循环从Matlab转换为C

来自分类Dev

将C for循环转换为MIPS

来自分类Dev

将for循环转换为Task.Parallel.For

来自分类Dev

jQuery:将每个函数转换为for循环

来自分类Dev

将嵌套循环转换为递归

来自分类Dev

Scala将For循环转换为函数方法

来自分类Dev

如何将for循环转换为变量?

来自分类Dev

将.each()转换为for循环jQuery

来自分类Dev

将嵌套的for循环转换为等效的地图

来自分类Dev

将if ... else语句转换为for循环