我有以下内容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(使用前将#替换为@)