【问题标题】:Run async function from sync as well as Async function c#从同步运行异步函数以及异步函数c#
【发布时间】:2015-03-23 20:52:10
【问题描述】:

我正在发送“异步”电子邮件。

我使用一个通用的“异步”函数来调用电子邮件函数,因为我不需要等待电子邮件的响应。

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 的目的。

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

【问题讨论】:

  • 您的根本问题是误解了在这种情况下编写异步代码的好处是触发并忘记-这不是这种异步的主要目的,它是在您释放线程时 等待任务完成——而不是简单地等待它。
  • 是的,我想我现在明白了。

标签: c# asynchronous


【解决方案1】:

您可以:

A) 创建一个“即发即弃”请求,就像您尝试做的那样。

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

方法 A 将使用 2 个线程,第一个是您的请求线程,第二个是 fire and forget 线程。这会从请求线程池中窃取一个线程,导致负载过重时线程饥饿。

方法B在有事情要处理的时候会花费1个线程..请求线程就是。

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

使用 Async/await 时,线程仅在 CPU 工作时处于活动状态,而在进行 IO 密集型工作时被释放以服务其他请求/任务。

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

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

如果你还想运行后台任务,read this blog post: Search Results How to run Background Tasks in ASP.NET - Scott Hanselman

【讨论】:

  • 我现在做的不是方法B吗?
  • @PatrickHofman 是的,但如果他希望他的请求立即返回,则必须启动一个新线程。
  • @Ruchan 是的,方法 B 是你已经在做的异步/等待。
  • 谁能解释为什么我必须使用await
  • ASP.NET 运行时告诉您您可能犯了一个错误。在工作完成之前返回请求并没有什么意义,除非您特别指定您希望它作为后台任务运行。在这里阅读更多:stackoverflow.com/questions/18502745/…
猜你喜欢
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 2020-04-20
相关资源
最近更新 更多