Ant*_*ony 27 c# lambda asynchronous async-await
lambdas () => DoSomethingAsync()
和async () => await DoSomethingAsync()
两者都输入时有区别Func<Task>
吗?我们应该选择哪一个?何时?
这是一个简单的控制台应用程序
using System;
using System.Threading.Tasks;
namespace asyncDemo
{
class Program
{
static void Main(string[] args)
{
var demo = new AsyncDemo();
var task = demo.RunTheDemo();
task.Wait();
Console.ReadLine();
}
}
public class AsyncDemo
{
public async Task Runner(Func<Task> action)
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + " Launching the action");
await action();
}
private async Task DoSomethingAsync(string suffix)
{
await Task.Delay(2000);
Console.WriteLine(DateTime.Now.ToLongTimeString() + " Done something, " + suffix);
}
public async Task RunTheDemo()
{
await Runner(() => DoSomethingAsync("no await"));
await Runner(async () => await DoSomethingAsync("with await"));
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
09:31:08 Launching the action
09:31:10 Done something, no await
09:31:10 Launching the action
09:31:12 Done something, with await
Run Code Online (Sandbox Code Playgroud)
因此RunTheDemo
,两个呼叫await Runner(someLambda);
似乎都以相同的时序特性做同样的事情 - 两者都有正确的两秒延迟.
这两条线都有效,它们完全相同吗?() => DoSomethingAsync()
和async () => await DoSomethingAsync()
构造之间有什么区别 ?我们应该选择哪一个?何时?
这不是"我应该await
在一般情况下使用"这个问题,因为我们正在处理异步代码,并且Func<Task>
在消费方法中正确等待lambdas类型.问题涉及如何宣布这些lambdas,以及该声明的影响是什么.
i3a*_*non 20
使用和不使用异步声明的lambdas之间是否存在差异
是的,有区别.一个是异步lambda,另一个是返回任务的lambda.
异步lambda被编译成一个状态机,而另一个则没有,因此异步lambda具有不同的异常语义,因为异常被封装在返回的任务中并且不能同步抛出.
这与常规方法中存在的完全相同.例如,这种异步方法之间:
async Task FooAsync()
{
await DoSomethingAsync("with await");
}
Run Code Online (Sandbox Code Playgroud)
而这个任务返回方法:
Task FooAsync()
{
return DoSomethingAsync("no await");
}
Run Code Online (Sandbox Code Playgroud)
查看这些方法可以更清楚地显示差异,但由于lambdas只是语法糖,实际上编译成与这些方法行为相同的方法.
我们应该选择哪一个?何时?
这真的取决于你的口味.使用async关键字会生成一个状态机,其性能不如简单地返回任务.但是,在某些情况下,异常语义可能会令人惊讶.
以此代码为例:
Hamster hamster = null;
Func<Task> asyncAction = () => FooAsync(hamster.Name);
var task = asyncAction();
try
{
await task;
}
catch
{
// handle
}
Run Code Online (Sandbox Code Playgroud)
try-catch块会处理NullReferenceException
还是不处理?
它不会因为在调用时同步抛出异常 asyncAction
.但是,在这种情况下将处理异常,因为它在返回的任务中捕获,并在等待该任务时重新抛出.
Func<Task> asyncAction = async () => await FooAsync(hamster.Name);
Run Code Online (Sandbox Code Playgroud)
我个人使用返回任务的lambda作为这一行的表达式lambdas,因为它们通常很简单.但是我的团队在经历了一些非常有害的错误后,总是使用async
和await
关键字.
归档时间: |
|
查看次数: |
1232 次 |
最近记录: |