简体   繁体   English

我可以从普通同步方法调用可等待的异步方法吗?

[英]Can I call awaitable async method from normal synchronous method?

I have code in ASP.net that sends an email.我在 ASP.net 中有发送电子邮件的代码。 My application is older using ASP.net Webforms and is not converted over to async methods.我的应用程序使用 ASP.net Webforms 较旧,并且未转换为异步方法。

However the method for sending email via SendGrid is async awaitable.然而,通过 SendGrid 发送电子邮件的方法是异步等待的。

Visual Studio doesn't complain if I use a discard:如果我使用丢弃,Visual Studio 不会抱怨:

_  = SendASendGridMessage()

Would this cause any crash or deadlock if I do this?如果我这样做会导致任何崩溃或死锁吗?

Here is the sample code:这是示例代码:

public static void SendNew(string toEmail, string subject, string htmlContent, int domainId, int partyId, string category, int itemId)
{           
    EmailAddress from = new EmailAddress("example@example.com");
    EmailAddress to = new EmailAddress(toEmail);
    EmailAddress replyTo = new EmailAddress("example@example.com");
            
    htmlContent = $"<html><body>{htmlContent}</body></html>";           

    var msg = MailHelper.CreateSingleEmail(from, to, subject, null, htmlContent);

    _ = SendASendGridMessage(msg, domainId);
}

// Which will then connect with this method later:

// Summary:
// Make a request to send an email through Twilio SendGrid asynchronously.
//
// Parameters:
//   msg:
//     A SendGridMessage object with the details for the request.
//
//   cancellationToken:
//     Cancel the asynchronous call.
//
// Returns:
//     A Response object.
[AsyncStateMachine(typeof(<SendEmailAsync>d__23))]
public Task<Response> SendEmailAsync(SendGridMessage msg, CancellationToken cancellationToken = default);

You can use "Fire and Forget" approach and just call an async method without await just like you did.您可以使用“即发即弃”的方法,只需像您一样调用异步方法而无需await In fact, it is a good practice to detach time-consuming operations, such as sending emails from the code handling http requests.事实上,分离耗时的操作是一个很好的做法,例如从处理 http 请求的代码中发送电子邮件。 One thing you need to keep in mind, is that an ASP.NET web application is treated as stateless and the host can decide to off-load your app at any moment, even before your async method completes.您需要记住的一件事是,ASP.NET Web 应用程序被视为无状态,主机可以随时决定卸载您的应用程序,甚至在您的异步方法完成之前。

There is a mechanism in ASP.NET Framework to schedule long lasting activities so that the Host will be able to gracefully terminate your application waiting for the scheduled activities ASP.NET Framework 中有一种机制来安排持久的活动,以便主机能够优雅地终止您的应用程序,等待安排的活动

HostingEnvironment.QueueBackgroundWorkItem HostingEnvironment.QueueBackgroundWorkItem

using System.Web.Hosting;

...

// Schedule task in a background tread 
Func<CancellationToken, Task> workItem = ct => SendASendGridMessage(...);
HostingEnvironment.QueueBackgroundWorkItem(workItem);

You could use something like this:你可以使用这样的东西:

Task t = new Task(() =>
  {
    if (something == true) 
    {
        DoSomething(e);  
    }
  });
  t.RunSynchronously();

For more details, on this topic you can look at the following:有关此主题的更多详细信息,您可以查看以下内容:

Synchronously waiting for an async operation, and why does Wait() freeze the program here 同步等待一个异步操作,为什么Wait()会在这里冻结程序

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

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