在异步方法返回,等待任务的区别区别、任务、方法

2023-09-03 00:17:23 作者:落雨,繁花

有没有下面的方法有什么区别?是preferable比其他?

 公共静态异步任务SendAsync1(字符串,字符串主题,串htmlBody){
  // ...
  等待smtp.SendMailAsync(消息);
  //没有return语句
}

公共静态任务SendAsync2(字符串,字符串主题,串htmlBody){
  // ...
  返回smtp.SendMailAsync(消息);
}
 

此方法将会从MVC控制器方法调用;例如:

 公共异步任务<的ActionResult> RegisterUser(RegisterViewModel模型)
{
  // ...
  等待Mailer.SendAsync(user.Email,主题,正文);
  返回查看(模型);
}
 

解决方案 C 怎么调用方法

有2实际差别:

在第二个选项不会创建状态机mecanism,允许异步计谋的使用。这将有一个的轻微的业绩的积极影响。 在异常处理将是一个有点不同。当你标记方法,异步的任何异常都存储在返回的任务(无论是从异步部分和同步的),只有抛出当任务等待(或等待)。如果这不是异步,从同步部件的异常行为就像任何其他的方法。

我的建议:使用第二个为添加的性能提升,但留意的异常和缺陷

这显示了不同的一个例子:

 公共静态异步任务测试()
{
    任务挂起= Task.FromResult(真正的);
    尝试
    {
        未决= SendAsync1();
    }
    赶上(例外)
    {
        Console.WriteLine(1同步);
    }

    尝试
    {
        等待悬而未决;
    }
    赶上(例外)
    {
        Console.WriteLine(1  - 异步);
    }

    未决= Task.FromResult(真正的);
    尝试
    {
        未决= SendAsync2();
    }
    赶上(例外)
    {
        Console.WriteLine(2-同步);
    }

    尝试
    {
        等待悬而未决;
    }
    赶上(例外)
    {
        Console.WriteLine(2-异步);
    }
}

公共静态异步任务SendAsync1()
{
    抛出新的异常(同步异常);
    等待Task.Delay(10);
}

公共静态任务SendAsync2()
{
    抛出新的异常(同步异常);
    返回Task.Delay(10);
}
 

输出:

  1,异步
2同步
 

Is there any difference between the methods below? Is one preferable over the other?

public static async Task SendAsync1(string to, string subject, string htmlBody) {
  // ...
  await smtp.SendMailAsync(message);
  // No return statement
}

public static Task SendAsync2(string to, string subject, string htmlBody) {
  // ...
  return smtp.SendMailAsync(message);
}

This method will be called from MVC controller methods; for example:

public async Task<ActionResult> RegisterUser(RegisterViewModel model)
{
  // ...
  await Mailer.SendAsync(user.Email, subject, body);
  return View(model);
}

解决方案

There are 2 practical differences:

The second option will not create the state machine mecanism that allows for async-await usage. That will have a minor positive effect on performance. The exception handling would be a little different. When you mark a method as async any exceptions are stored in the returned task (both from the asynchronous part and the synchronous one) and thrown only when the task is awaited (or waited). When it's not async, the exceptions from the synchronous parts act just like in any other method.

My suggestion: Use the second one for the added performance boost but keep an eye out for exceptions and bugs.

An example that shows the difference:

public static async Task Test()
{
    Task pending = Task.FromResult(true);
    try
    {
        pending = SendAsync1();
    }
    catch (Exception)
    {
        Console.WriteLine("1-sync");
    }

    try
    {
        await pending;
    }
    catch (Exception)
    {
        Console.WriteLine("1-async");
    }

    pending = Task.FromResult(true);
    try
    {
        pending = SendAsync2();
    }
    catch (Exception)
    {
        Console.WriteLine("2-sync");
    }

    try
    {
        await pending;
    }
    catch (Exception)
    {
        Console.WriteLine("2-async");
    }
}

public static async Task SendAsync1()
{
    throw new Exception("Sync Exception");
    await Task.Delay(10);
}

public static Task SendAsync2()
{
    throw new Exception("Sync Exception");
    return Task.Delay(10);
}

Output:

1-async
2-sync