当不使用Task.Run()安排工作时如何处理并发性?

问题描述 投票:1回答:3

如果我们填写需要同时完成CPU绑定和I / O绑定工作的任务列表,只需将其方法声明传递到该列表即可(而不是通过创建新任务并使用Task.Start手动进行调度) ,这些任务的处理方式如何?

我知道它们不是并行执行的,而是并行执行的。

这是否意味着一个线程将沿着它们移动,并且那个线程可能不是线程池中的同一线程,或者不是最初开始等待它们全部完成/添加到列表中的线程?] >

EDIT:

我的问题是关于如何在列表中同时精确地处理这些项目-调用线程正在它们中移动还是发生其他事情?

需要代码的代码:

public async Task SomeFancyMethod(int i)
{
    doCPUBoundWork(i);
    await doIOBoundWork(i);
}


//Main thread

List<Task> someFancyTaskList = new List<Task>();
for (int i = 0; i< 10; i++)
    someFancyTaskList.Add(SomeFancyMethod(i));
// Do various other things here --
// how are the items handled in the meantime?
await Task.WhenAll(someFancyTaskList);

谢谢。

如果通过简单地将其方法声明传递到该列表来填充既需要完成CPU绑定又需要I / O绑定的任务的列表(而不是通过创建新任务并使用...手动进行调度,则通过该任务进行...) >

c# .net asynchronous .net-core async-await
3个回答
4
投票

异步方法总是开始同步运行。魔术发生在第一个await。当await关键字看到incomplete

Task时,它返回自己的不完整Task。如果看到complete

2
投票

我假设您不是要传递其方法declaration

,而只是调用该方法,如下所示:

1
投票

这里是您的代码在没有异步/等待的情况下进行了重写,而改用老式的延续。希望它将使人们更容易理解正在发生的事情。

public Task CompoundMethodAsync(int i)
{
    doCPUBoundWork(i);
    return doIOBoundWorkAsync(i).ContinueWith(_ =>
    {
        doMoreCPUBoundWork(i);
    });
}

// Main thread
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
    Task task = CompoundMethodAsync(i);
    tasks.Add(task);
}
// The doCPUBoundWork has already ran synchronously 10 times at this point

// Do various things while the compound tasks are progressing concurrently

Task.WhenAll(tasks).ContinueWith(_ =>
{
    // The doIOBoundWorkAsync/doMoreCPUBoundWork have completed 10 times at this point
    // Do various things after all compound tasks have been completed
});

// No code should exist here. Move everything inside the continuation above.
© www.soinside.com 2019 - 2024. All rights reserved.