我对此代码感到困惑。 根据包含此代码的文档, 它调用允许它们执行的每个任务 同时,然后等待他们两个完成。
我不明白执行顺序是如何运作的。通过声明任务var firstTask = DoSomethingAsync();
,这会导致任务开始执行吗?我认为没有await表达式就是同步的。
public async Task RunConcurrentTasks()
{
var firstTask = DoSomethingAsync();
var secondTask = DoSomethingElseAsync();
await firstTask;
await secondTask;
}
此外,此代码是否实现了相同的结果?
public async Task RunConcurrentTasks()
{
var firstTask = DoSomethingAsync();
var secondTask = DoSomethingElseAsync();
await Task.WhenAll(firstTask, secondTask);
}
答案 0 :(得分:6)
var firstTask = DoSomethingAsync();
这会导致任务开始执行吗?
是。它更好! DoSomethingAsync
在其名称中承诺以异步方式执行某些操作,因此,如果它不会将您送回执行任务,那么它的名称就是谎言。
执行如何进入下一行以调用第二个任务?
我不明白这个问题。
我认为没有等待表达式就是同步的。
你的信念是错误的。 "等待"并不意味着"使这个异步"。等待既不创造也不破坏异步;它只管理现有的异步。 DoSomethingAsync
已经异步独立于任何await
。再次,它表示它以异步方式执行某些操作,因此最好能够做到这一点!
await
仅为return
。这意味着"返回我的调用者,并在等待任务完成后的某个时间再次开始运行此方法。"它是异步等待。
将await
视为yield return
。当您在迭代器块中并且遇到收益率返回时,该方法返回,然后它将在未来的某个时刻从中断处继续。 await
基本相同;只是机制略有不同。
另一种思考方式是await
标记当前方法无法继续运行直到等待任务完成的点。由于该方法无法继续运行,因此返回。
同样,await
对其右侧的呼叫不执行任何操作。它只是一个运营商,它遵守运营商的所有正常规则:
await Foo();
和
var blah = Foo();
await blah;
是一样的,就像
一样var x = Foo() + Bar();
和
var f = Foo();
var b = Bar();
var x = f + b;
是一回事。 Await不会为其操作数做一些神奇的事情,而不仅仅是+
对其操作数做了一些神奇的事情。这只是一种特殊的回报。
此外,此代码是否也做同样的事情?
请不要在一个问题中提出两个问题。如果您有两个问题,请发两个问题。
问题不明确。这两个工作流的语义是RunConcurrentTasks返回的任务在其子任务完成时发出信号,如果这是你要求的话。
答案 1 :(得分:1)
通过声明任务var firstTask = DoSomethingAsync();这会导致任务开始执行吗?
是
执行如何进入下一行以调用第二个任务?
它将运行DoSomethingAsync
,直到它达到其产生的第一个await
。此时,DoSomethingAsync
返回尚未完成的任务,并且调用者RunConcurrentTasks
继续到下一行。
我认为没有等待表达式就是同步的。
不,它仍然是异步的。 await
无法运行任何内容。 await
将导致消费代码异步等待("等待")以使任务完成。
您可能会发现我的async
intro有帮助。
答案 2 :(得分:0)
在调用异步方法时,使用parenthesys ()
,例如DoSomethingAsync();
将开始执行异步功能。它将立即返回Task
,其中包含有关正在执行的异步功能的信息,并让系统知道它何时完成。
要按顺序运行它们,只需等待每一个而不是等待WhenAll
调用。就这样:
public async Task RunConcurrentTasks()
{
await DoSomethingAsync();
await DoSomethingElseAsync();
}
现在DoSomethingElseAsync
会在执行前等待DoSomethingAsync
的调用。
答案 3 :(得分:0)
Task类表示一个不返回值且通常执行异步的操作。任务对象是.NET Framework 4中首次引入的基于任务的异步模式的核心组件之一。因为Task对象执行的工作通常在线程池线程上异步执行,而不是在主应用程序线程上同步执行。
这是您的代码注释,希望这更有意义。
public async Task RunConcurrentTasks()
{
// starts DoSomethingAsync and returns a Task which contains the information about the running state of that operation
// the thread that called this gets that Task as a result immediatly and can continue on to the next statement while this is running
var firstTask = DoSomethingAsync();
// starts DoSomethingElseAsync and returns a Task which contains the information about the running state of that operation
// the thread that called this gets that Task as a result immediatly and can continue on to the next statement while this is running
var secondTask = DoSomethingElseAsync();
// suspend the execution of the method until the awaited task completes
// only then do we proceed to the next line (assuming no exception was thrown)
await firstTask;
// suspend the execution of the method until the awaited task completes
// only then do we proceed to the next line (assuming no exception was thrown)
await secondTask;
}
public async Task RunConcurrentTasks()
{
// starts DoSomethingAsync and returns a Task which contains the information about the running state of that operation
// the thread that called this gets that Task as a result immediatly and can continue on to the next statement while this is running
var firstTask = DoSomethingAsync();
// starts DoSomethingElseAsync and returns a Task which contains the information about the running state of that operation
// the thread that called this gets that Task as a result immediatly and can continue on to the next statement while this is running
var secondTask = DoSomethingElseAsync();
// suspend the execution of the method until the awaited DoSomethingAsync AND DoSomethingElseAsync have completed
// only then do we proceed to the next line (assuming no Exceptions was thrown)
await Task.WhenAll(firstTask, secondTask);
}
来自评论
如果我愿意,我如何同步进行?
await运算符应用于异步方法中的任务,以暂停方法的执行,直到等待的任务完成为止
每次调用后立即使用await
,这可确保执行不会继续执行下一行,直到从等待执行的任务返回结果(或异常)。 它实际上并没有在技术意义上使它同步。因此,请参考第一个示例并重新排序行,以便在开始第一个操作之后和开始之前调用await
第二次手术。
var firstTask = DoSomethingAsync();
await firstTask;
var secondTask = DoSomethingElseAsync();
await secondTask;
也可以改写为
await DoSomethingAsync();
await DoSomethingElseAsync();