异步等待一个简单的包装方法

async await for a simple wrapper method

如果我编写的方法只是包装一个异步方法,例如:

public async Task WrapMethodAsync()
{
    using(var smtpClient = new SmtpClient())
    {
        await smtpClient.SendMailAysnc(new MailMessage());
    }
}

这是否与执行以下操作相同:

public Task WrapMethodAsync()
{
    using(var smtpClient = new SmtpClient())
    {
        return smtpClient.SendMailAysnc(new MailMessage());
    }
}

或者后者实际上不是 运行 异步的?

第一个片段在发送邮件后处理客户端,后者在开始发送邮件后但尚未完成时处理客户端。假设客户端在发送消息时不应该被释放,这意味着第一个解决方案是非常有问题的。

此外,错误处理语义不同;在第一个代码段中构造 Task 的异常将导致方法抛出异常,而在第二个代码段中它们导致 return 任务被标记为 Faulted 并设置了适当的异常.

在这种情况下,由于 using 范围,这两种情况 截然不同

在第一种情况下,您会(异步地)等待 SendMailAysnc 操作完成,然后再处理客户端,而在另一种情况下,您不会等待 处理客户端而操作仍然是运行.

在一般情况下,一般行为没有差异。例如:

public async Task Run()
{
    throw new Exception("stored");
    await Task.Delay(-1);
}

对比这个:

public Task Run()
{
    throw new Exception("thrown");
    return Task.Delay(-1);
}

不同之处在于 async 方法对整个 async 机制(包括状态机)有 轻微的 开销,而非 async 任务返回方法具有不同的异常语义,因为异常是 直接抛出而不存储在返回的任务中 .