这个使用TaskCompletionSource的异步方法有意义吗?

时间:2021-10-06 06:55:16

I'am trying to understand a piece of code that hasn't been written by myself. It's an async method for sending an email and should try up to 5 times to send a given mailmessage.

我试图理解一段我自己没有写过的代码。这是发送电子邮件的异步方法,最多可以尝试5次发送给定的邮件消息。

public Task<bool> SendMail(MailMessage mailMessage)
{
    bool success = false;

    int i = 0;
    int smtpRetryCount = 5;
    SmtpClient smtpClient = new SmtpClient("myprovider.de");
    smtpClient.Port = 123;
    smtpClient.EnableSsl = true;

    int smtpRetryWaitTime = 2000;

    while (i < smtpRetryCount + 1)
    {
        try
        {
            smtpClient.Send(mailMessage);
            success = true;
            Console.WriteLine("SUCCESS");
            break;
        }
        catch (Exception exc)
        {
            Console.WriteLine("Exception");
            Thread.Sleep(smtpRetryWaitTime);
            success = false;
        }

        i++;
    }

    // This is the part that I don't get, does it make any sense?
    TaskCompletionSource<bool> tsc = new TaskCompletionSource<bool>();
    tsc.SetResult(success);
    return tsc.Task;
}

I'm wondering if this is really async and if so, in which way it implements async properties. For me it doesn't make much sense, especially the last 4 lines.

我想知道这是否真的是异步,如果是这样,它实现了异步属性。对我来说这没有多大意义,特别是最后4行。

1 个解决方案

#1


3  

It's done this way because you want your API to be potentially asynchronous, while the implementation decides either if it's actually asynchronous or synchronous.

它是以这种方式完成的,因为您希望您的API可能是异步的,而实现则决定它是实际异步还是同步。

For that matter, you can either use TaskCompletionSource<TResult>, Task.FromResult<TResult>(TResult result), Task.FromCanceled or Task.FromException.

就此而言,您可以使用TaskCompletionSource ,Task.FromResult (TResult result),Task.FromCanceled或Task.FromException。

Why it's advised to go for this approach?

Usually you follow this approach/principle because you can easily make the same API to work asynchronously by swapping the implementation, while turning an already synchronous API into asynchronous one requires an intensive and long refactoring to make the change ever possible.

通常,您遵循这种方法/原则,因为您可以通过交换实现轻松地使相同的API异步工作,同时将已经同步的API转换为异步API需要进行密集且长时间的重构以使更改成为可能。

At the end of the day, you shouldn't find great differences implementing your APIs this way thanks to the wonders of awaitables and async-await

在一天结束时,由于等待和异步等待的奇迹,您不应该发现以这种方式实现API的巨大差异

#1


3  

It's done this way because you want your API to be potentially asynchronous, while the implementation decides either if it's actually asynchronous or synchronous.

它是以这种方式完成的,因为您希望您的API可能是异步的,而实现则决定它是实际异步还是同步。

For that matter, you can either use TaskCompletionSource<TResult>, Task.FromResult<TResult>(TResult result), Task.FromCanceled or Task.FromException.

就此而言,您可以使用TaskCompletionSource ,Task.FromResult (TResult result),Task.FromCanceled或Task.FromException。

Why it's advised to go for this approach?

Usually you follow this approach/principle because you can easily make the same API to work asynchronously by swapping the implementation, while turning an already synchronous API into asynchronous one requires an intensive and long refactoring to make the change ever possible.

通常,您遵循这种方法/原则,因为您可以通过交换实现轻松地使相同的API异步工作,同时将已经同步的API转换为异步API需要进行密集且长时间的重构以使更改成为可能。

At the end of the day, you shouldn't find great differences implementing your APIs this way thanks to the wonders of awaitables and async-await

在一天结束时,由于等待和异步等待的奇迹,您不应该发现以这种方式实现API的巨大差异