gpt4 book ai didi

c# - 将循环转换为任务

转载 作者:可可西里 更新时间:2023-11-01 08:15:56 25 4
gpt4 key购买 nike

我有以下同步代码:

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();
}

最佳答案

让我们找出代码中的问题:

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

这会返回一个冷的Task,这意味着Task 并没有真正开始。为了启动它,您需要调用:

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

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

If I use instead await Task.Run( () => step.Run() ); it awaits only the first one and resumes the main thread.

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

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

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

一旦 RunAsync 完成,这将保证所有任务都已完成执行。

关于c# - 将循环转换为任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29764664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com