运行 来自同步的异步函数以及异步函数 c#

Run async function from sync as well as Async function c#

我正在发送 'Async' 封电子邮件。

我使用常用​​的 'Async' 函数来调用电子邮件函数,因为我不需要等待电子邮件的回复。

public Task SendAsync(....)
{
      ....
      return mailClient.SendMailAsync(email);
}

我需要从 asyncsync 函数中调用它。

从异步函数调用

public async Task<ActionResult> AsyncFunction(...)
{
   ....
   EmailClass.SendAsync(...);
   ....
   // gives runtime error.
   // "An asynchronous module or handler completed while an asynchronous operation was still pending..."
   // Solved by using 'await EmailClass.SendAsync(...);'
}

从同步函数调用

public ActionResult syncFunction(...)
{
   ....
   EmailClass.SendAsync(...);
   ....
   // gives runtime error. 
   // "An asynchronous operation cannot be started at this time..."
   // Solved by converting the function as above function
}

这两个函数都会给出运行时错误,然后通过在异步函数中使用 await 关键字来解决。

但是使用 await 它违背了我 running it on background without waiting for response 的目的。

如何在不等待响应的情况下调用异步函数?

您可以:

A) 创建一个 'Fire and Forget' 请求,就像您尝试做的那样。

B) 等待异步请求的结果。

方法 A 将使用 2 个线程,第一个是您的请求线程,第二个是即发即弃线程。这会从请求线程池中窃取一个线程,导致在重负载下线程饥饿。

当有事情要处理时,方法 B 将花费 1 个线程..请求线程。

方法 B 将消耗更少的资源,而方法 A 可能会快几毫秒,但要以线程为代价(阅读:昂贵!)。

使用 Async/await 时,线程仅在执行 CPU 工作时处于活动状态,并在执行 IO 绑定工作时释放出来为其他 requests/tasks 服务。

在启动一个新线程时,将阻塞该线程直到它完成(除非你想做一些复杂的线程同步)。

TL;DR : Async/Await 效率更高,如果您选择使用即弃即弃,您最终会饿死您的网络服务器。

如果您仍想 运行 后台任务,阅读此博客 post:搜索结果 如何 运行 ASP.NET 中的后台任务 - Scott Hanselman