.net 如何使for循环中的void方法异步运行[已关闭]

wz1wpwve  于 2023-01-14  发布在  .NET
关注(0)|答案(3)|浏览(160)

12小时前关门了。
Improve this question
我有一个for循环,在这个for循环中,有一个void方法,这个方法通常需要花费时间,我想以async的方式运行这个void方法,并且想在doStuff(ele)完成之后,为list中的所有ele调用printFinalMessage()

for (int ele in list)
{
    doStuff(ele);
}

printFinalMessage()

会很感激你的帮助。

vyswwuz2

vyswwuz21#

我建议只使用Parallel.ForEach循环,这将 * 并发地 * 处理元素,而不是 * 异步地 * 处理元素,这意味着循环将进行得更快,但printFinalMessage将仅在所有元素实际完成处理时才被打印:

Parallel.ForEach(list, ele => {
    doStuff(ele);
}
printFinalMessage();

这里假设doStuff是一个常规的同步方法,如果它返回一个任务,你可能应该使用Task.WhenAll来创建一个任务,表示所有任务的完成。
您可能还想在后台任务中运行整个循环,这样在循环运行时UI就不会冻结。

pdkcd3nj

pdkcd3nj2#

问题的关键字是等待所有任务这是microsoft的reference,将任务添加到列表中并等待所有任务。注意DoStuff()的签名是Task

var list = new List<int>() { 1, 2, 3};

var taskList = new List<Task>();

foreach(var ele in list)
{
    taskList.Add(DoStuff(ele));
    //or you can write like
    //var task = DoStuff(ele); 
    //taskList.Add(task);
}

await Task.WhenAll(taskList);

public Task DoStuff(int ele){ }
aamkag61

aamkag613#

@JonasH说了什么,但如果你让doStuff异步¹,那么你可以使用Parallel.ForEachAsync ²:

ParallelOptions parallelOptions = new () { MaxDegreeOfParallelism = N };

var list = new List<int>() { 1, 2, 3 };

await Parallel.ForEachAsync(
    source: list,
    parallelOptions,
    async (i, cancellationToken) =>
    {
        await Task.Delay(TimeSpan.FromSeconds(i), cancellationToken); 
        // or await doStuffAsync(i, cancellationToken);
    });

printFinalMessage(); // Called all work (3 pieces of work in this example) is done.

¹ -真实的的异步;不是假装异步,例如-Task.FromResult
² -可从.NET 6获得

相关问题