C# 异步/等待执行步骤
谁能给我解释一下为什么secondC# 异步/等待执行步骤,c#,C#,谁能给我解释一下为什么second工作在完成后显示 Stating Doing Work Working! Done Working! Work completed 第二个问题为什么我不能像下面这样得到任务结果: Task result = await LongOperation(); 最后一个问题是,在我的代码中使用Task.Run代表wait/async的原因是什么?在哪里可以使用它,或者使用它不好 class Program { static void Main(string[
工作代码>在完成后显示
Stating
Doing Work
Working!
Done
Working!
Work completed
第二个问题为什么我不能像下面这样得到任务结果:
Task result = await LongOperation();
最后一个问题是,在我的代码中使用Task.Run
代表wait/async的原因是什么?在哪里可以使用它,或者使用它不好
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting");
var worker = new Worker();
worker.DoWork();
Console.WriteLine("Done");
Console.ReadKey();
}
}
public class Worker
{
public async void DoWork()
{
Console.WriteLine("Doing work");
await LongOperation();
await LongOperation();
Console.WriteLine("Work completed");
}
private async Task LongOperation()
{
Console.WriteLine("Working!");
await Task.Delay(200);
}
}
这是因为您声明了DoWork()
异步,返回类型为void
。这使得它成为一个异步运行的“触发并忘记”方法。如果您有DoWork()
返回一个任务而不是void
,您可以等待它,这将确保在DoWork()
完成执行后出现“完成”消息
此外,await
将打开任务结果,因此您不能等待它并同时获取值。如果您希望直接使用任务
结果,请不要等待它
代码中没有指定您应该在哪里使用任务的特定区域。Run()
出现“Done!”的原因比您预期的要早,因为您没有在worker.DoWork()前面等待
(并且DoWork
需要返回任务
,才能使用等待
)。因此,所发生的是DoWork()
立即返回,执行延迟到另一个线程,并立即转到下一行,即控制台写入“done”
关于任务结果=等待长时间操作()
,等待
作为参数等待对象(即任务
),代表您检查其。结果
属性,提取结果并返回。因此,您要么删除wait
以获取任务实例,要么放入wait
以等待任务完成并提取调用的实际返回值
使用任务有几个原因。运行或通过任务工厂,一个例子是传递lambda函数以执行(可能带有闭包)。我会参考第三方物流上的MSDN库了解详细信息
工作
在完成后显示代码>因为在您的静态void Main
中,您没有等待worker.DoWork()代码>完成,因此程序执行下一行。您应该像这样更改DoWork
方法:
public async Task DoWork()
{
//
}
worker.DoWork().GetAwaiter().GetResult();
然后按如下方式更改对它的调用:
public async Task DoWork()
{
//
}
worker.DoWork().GetAwaiter().GetResult();
您不能这样做,因为使用wait
您的long操作将不会返回任务
。例如,如果您有这样的签名,当您使用wait
时,您将打开结果:
public Task<int> GiveANumberAsync()
{
return Task.FromResult(12);
}
int result = await GiveANumberAsync();
public任务GiveANumberAsync()
{
返回任务.FromResult(12);
}
int result=wait GiveANumberAsync();
对于这个问题,我想我无法比斯蒂芬更好地解释,他说:
使用Task.Run调用CPU绑定的方法
逐一回答您的问题:
在Main
中,您不需要等待DoWork
。这意味着调用它,然后继续执行Main
中的代码,而无需等待DoWork
完成。因此,在第二次“工作”之前,立即将“完成”打印到控制台
这不是await
关键字所做的。从:
等待运算符应用于异步方法中的任务,以暂停方法的执行,直到等待的任务完成。这项任务是正在进行的工作。[...]
应用wait运算符的任务通常是对实现基于任务的异步模式的方法的调用的返回值。示例包括Task
或Task
类型的值
实际上,为了等待一个方法,它必须具有返回类型Task
,其中T是代码中返回的实际类型。在本例中,您的方法LongOperation
实际上不会返回任何内容
Task.Run
用于将任何方法或代码块作为任务运行。它可以被触发和遗忘(Task.Run([something];
),也可以像任何其他任务一样等待(wait Task.Run([something]);
。请参阅相关文档,尽管我不确定它会有多大帮助。用户对此进行了很好的解释,并提供了一些其他相关信息
1.因为您调用了两次LongOperation
。2.因为这不是await
的工作方式。3.异步调用同步操作。(以后,请尽量在每篇帖子中只回答一个问题。)请看。你应该避免在同一个线程中问多个问题。此外,如果你提供一些关于你所问问题的上下文(特别是在第一个问题中),这将使我们更容易理解表示。您不能等待无效返回类型。请尝试避免无效语法。不控制任务激发和forgetCPU绑定方法是最常用的使用方法