async等待一个简单的包装器方法

时间:2015-03-25 19:46:33

标签: c# .net asynchronous async-await task-parallel-library

如果我编写的方法只包含异步方法,例如:

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());
    }
}

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

2 个答案:

答案 0 :(得分:7)

在这种情况下,由于using范围,这两种情况极不相同

在第一种情况下,您等待(异步)以便在处理客户端之前完成SendMailAysnc操作,而在另一种情况下,您不会这样做在操作时处置客户端仍在运行

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

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

VS这个:

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

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

答案 1 :(得分:4)

第一个代码段在邮件发送后处理客户端,后者在启动发送邮件之后但在它完成之前处理客户端。假设客户端在发送消息时不应该被丢弃,这意味着第一个解决方案存在问题。

此外,错误处理语义不同;在第一个代码段中构造Task的异常将导致该方法抛出异常,而在第二个代码段中,它们会导致返回任务被标记为Faulted并具有相应的异常集。