调用异步方法时什么情况下使用.Wait()

2024-05-20

我有以下内容async我的 asp.net mvc-5 Web 应用程序中长时间运行的方法:-

 public async Task<ScanResult> ScanAsync(string FQDN)
 {
    // sample of the operation i am doing 
    var c = await context.SingleOrDefaultAsync(a=>a.id == 1);
    var list = await context.Employees.ToListAsync();
    await context.SaveChangesAsync();
    //etc..
}

我正在使用 Hangfire 工具,它支持运行后台作业来及时调用此异步方法,但不幸的是,hangefire 工具不支持直接调用异步方法。因此,为了克服这个问题,我创建了上述方法的同步版本,如下所示:-

public void Scan()
{
    ScanAsync("test").Wait();
}

然后从 HangFire 调度程序中我调用同步方法如下:-

RecurringJob.AddOrUpdate(() => ss.Scan(), Cron.Minutely);

所以我知道使用.Wait()在方法执行期间将主要占用iis线程,但是正如我提到的,我需要以这种方式执行,因为我不能直接调用hangefire调度程序内的异步任务。

那么当我使用时会发生什么.Wait()调用异步方法?整个方法的操作会以同步方式完成吗?例如,如上所示,我在里面有三个异步操作ScanAsync() ;SingleOrDefualtAsync,ToListAsync & SaveChangesAsync,那么它们是否会以同步方式执行,因为我使用 .wait() 调用 ScanAsync 方法?


那么当我使用 .Wait() 调用异步方法时会发生什么? 整个方法的操作会以同步方式完成吗?例如 如上所示,我在 ScanAsync() 中有三个异步操作 ;SingleOrDefualtAsync、ToListAsync 和 SaveChangesAsync,所以它们会是 以同步方式执行,因为我正在使用调用 ScanAsync 方法 。等待() ?

查询数据库的方法仍然会异步执行,但事实上您正在调用Wait意味着即使您释放该线程,它也不会返回到您持有的 ASP.NET ThreadPool。

这也可能导致死锁,因为 ASP.NET 有一个自定义同步上下文,可确保请求的上下文在继续异步调用时可用。

相反,我建议您使用实体框架提供的同步 API,因为您实际上不会享受从异步调用中获得的可扩展性。

Edit:

在评论中,您问:

正如我目前正在使用hangefire 消除异步效果?如果是,那么使用同步方法会更好吗?或者使用sync或async与hangeffire将完全相同

首先,您必须了解异步的好处是什么。你这样做不是因为它很酷,而是因为它有一个目的。那目的是什么?能够scale在负载下。它是如何做到的?当你await异步方法,控制权返回给调用者。例如,您有一个传入请求,您查询数据库。您可以坐在那里等待查询完成,也可以重新使用该线程来服务更多传入的请求。这才是真正的力量。

如果您实际上并不打算接收相当数量的请求(这样您就会耗尽线程池),那么您实际上不会看到异步带来的任何好处。目前,按照您实现它的方式,您不会看到任何这些好处,因为您阻止了异步调用。您可能会看到的只是僵局。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用异步方法时什么情况下使用.Wait() 的相关文章

  • 异步提交或回滚事务范围

    正如许多人所知 TransactionScope当async await Net 中引入了模式 如果我们尝试使用一些它们就会损坏await在事务范围内调用 现在这个问题已经解决了 感谢范围构造函数选项 a 17527759 1178314
  • 当我在 C 中将 long int 赋值给 int 时会发生什么?

    在最近的作业中 我被告知要使用long变量来存储结果 因为它可能是一个很大的数字 我决定在我的系统 英特尔酷睿 i5 64 位 Windows 7 gnu gcc 编译器 上检查这对我来说真的很重要 并发现以下代码 printf sizeo
  • WebBrowser Control 导致整个应用程序变得无响应

    我有一个带有嵌入式 Web 浏览器的 C NET 3 5 应用程序 浏览器被设计为指向远程站点 而不是本地站点 一切工作正常 但是当页面响应缓慢时 这会导致我的整个应用程序变得无响应 直到加载页面 我不介意浏览器在执行任务时没有响应 但应用
  • 以编程方式获取命名管道的系统名称

    我正在使用 WCF NetNamedPipeBinding 编写进程间通信 我的目标是让服务在 net pipe localhost service 上运行 所以我运行最简单的主机 host new ServiceHost contract
  • Qt:更改 Mac OS X 上的应用程序 QMenuBar 内容

    我的应用程序对多个 页面 使用 QTabWidget 其中顶级菜单根据用户所在的页面而变化 我的问题是 尝试重新创建菜单栏的内容会导致严重的显示问题 它在除 Mac OS X 之外的所有平台上按预期使用第一种和第三种样式 尚未测试第二种 但
  • 为什么这些冲突出现在以下 XML 的 yacc 语法中

    我有以下 XML 语法 效果很好 program lt ID attribute list gt root root lt ID attribute list gt node list lt ID gt node list node s n
  • 返回带有列表对象的列表对象

    我有三个表 汽车品牌 汽车型号 和 CarsandModel 我有 Carsand 模型表 因为一个模型可以由多个制造商构建 我想返回包含汽车型号列表的汽车品牌列表 我现在的长篇大论不是过滤汽车型号的汽车制造商列表 我尝试添加一个 wher
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • 当假设 [[assume]] 包含 UB 时会发生什么?

    在 C 23 中 assume expression 属性使得如果表达 is false 行为未定义 例如 int div int x int y assume y 1 return x y 这会编译成相同的代码 就像y一直是1 div i
  • 如何使用 LINQ 对列表的列表进行分组(例如:List>)

    我知道我可以使用一些 for 循环轻松地做到这一点 但想看看是否有一种方法可以使用流畅的 LINQ 来做到这一点 我试图找出每个子列表中有多少个 我在看Enumerable SequenceEqual http msdn microsoft
  • MPI_Gather 分段错误

    我有这个并行高斯消除代码 调用以下任一方法时会发生分段错误MPI Gather函数调用 我知道如果没有为任一缓冲区正确分配内存 可能会出现此类错误 但我看不出内存管理代码有什么问题 有人可以帮忙吗 Thanks Notes 该程序从一个 t
  • 三元运算的结果(类型)是什么?

    三元运算是否返回副本或引用 我检查了以下代码 vector
  • SolrNet:尝试添加和提交时 SolrConnectionException (400) 错误请求

    我已经到了 SolrNet 执行 Add 方法的地步 但是当我尝试 Commit 时 我收到了错误 以下是我的 schema xml 模型 调用它的代码以及我得到的错误 更奇怪的是 尽管出现错误 但在我重新启动 Tomcat 后 该模型仍会
  • 使用 C 通过引用传递数组

    是的 我已经阅读了这个问题和答案 在 C 中通过引用传递数组 https stackoverflow com questions 1106957 pass array by reference in c 我有一个类似的问题 并从该问题中实现
  • 将 boost::iostreams::mapped_file_source 与 std::multimap 一起使用

    我有相当大量的数据需要分析 每个文件大约有 5gig 每个文件的格式如下 xxxxx yyyyy 键和值都可以重复 但键是按升序排列的 我正在尝试使用内存映射文件来实现此目的 然后找到所需的键并使用它们 这是我写的 if data file
  • 以编程方式打开网页并以字符串形式检索其 html 包含内容

    我有一个 Facebook 帐户 我想提取我朋友的照片及其个人详细信息 例如 出生日期 就读学校 等 我能够提取我每个朋友帐户的 Facebook 首页的地址 但我不知道如何以编程方式打开我每个朋友首页的网页并将 html 包含保存为字符串
  • 将 LPTSTR 转换为要写入文件的字符串或 char *

    我想将 LPTSTR 转换为字符串或 char 以便能够使用 ofstream 将其写入文件 有任何想法吗 Use T2A http msdn microsoft com en us library 87zae4a3 VS 80 aspx宏
  • 是否可以在 ASP.NET Web API 和 SPA 中使用基于 cookie 的身份验证?

    我想创建基于 angularjs 前端和 ASP NET Web API 的 Web 应用程序 我需要创建安全 api 但我无法在将实施此 Web 应用程序的公司服务器上使用基于令牌的身份验证 是否可以对 SPA 和 ASP NET Web
  • 为什么在 C++ 内存管理中术语“自动”和“动态”优于术语“堆栈”和“堆”?

    与 SO 上的许多问题和答案相关 我了解到最好将其生命周期管理为驻留在自动存储中而不是堆栈中的对象 此外 动态分配的对象不应该被称为驻留在堆上 而应该被称为驻留在动态存储中 我知道有自动 动态和静态存储 但从未真正理解自动堆栈和动态堆之间的
  • 同时使用多个控制台

    是否有捷径可寻 我现在仅使用控制台测试我的网络应用程序 最好的办法是从一个项目中拥有多个控制台 然后按一下 立即调试 菜单项 我可以像过去一样使用多个项目 但这似乎很笨拙 理想情况下 我可以启动多个控制台实例 从同一线程运行很好 并且让它们

随机推荐