简体   繁体   English

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

[英]async await for a simple wrapper method

If I write a method that is just wrapping an async method such as this: 如果我写的方法只是包装一个异步方法,例如:

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

Is that the same as doing the following: 与执行以下操作是否相同:

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

Or is the latter not actually running asynchronously? 还是后者实际上不是异步运行的?

In this exact scenario the two cases are extremely different because of the using scope. 在这种确切的情况下,由于using范围的原因,两种情况极为不同

In the first case you wait (asynchronously) for the SendMailAysnc operation to complete before disposing of the client while in the other case you don't so you would dispose of the client while the operation is still running . 在第一种情况下,您(异步地)等待SendMailAysnc操作完成,然后再处置客户端,而在另一种情况下,您不这样做,则在操作仍在运行时处置客户端

In the general case where there isn't a difference in the general behavior. 在一般情况下,一般行为没有差异。 For example this: 例如:

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

VS this: VS这:

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

The difference is that the async method has a slight overhead of the whole async mechanism (including a state machine) while the non- async task-returning method has a different exception semantics as exceptions are thrown directly and not stored in the returned task . 区别在于, async方法在整个async机制(包括状态机)上的开销很小 ,而非async任务返回方法则具有不同的异常语义,因为异常是直接引发的而不存储在返回的任务中

The first snippet disposes of the client after the mail is sent, the latter disposes of the client after it starts sending the mail, but before it has finished. 发送邮件后,第一个代码片段处理客户端, 开始发送邮件之后但完成之前,后者处理客户端。 Assuming the client isn't supposed to be disposed while it is sending messages, it means that the first solution is very problematic. 假设在发送消息时不应该丢弃客户端,这意味着第一个解决方案非常有问题。

Additionally, the error handling semantics are different; 另外,错误处理的语义是不同的。 exceptions in constructing the Task in the first snippet will result in the method throwing an exception, whereas in the second snippet they result in the return task being marked as Faulted with the appropriate exception set. 在第一个代码段中构造Task异常将导致方法抛出异常,而在第二个代码段中,它们将导致返回任务被标记为Faulted并带有适当的异常集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM