sol*_*ljy 2 asp.net asynchronous background async-await
假设我有以下异步方法,需要相当长的时间才能完成其工作:
void async Task LongWork()
{
await LONGWORK() // ... long work
}
Run Code Online (Sandbox Code Playgroud)
现在,在web api中,我想在后台运行该工作(即,我想在启动LongWork()之后但在完成之前返回Http请求:
我可以想到实现这个目标的三种方法:
1) public async Task<string> WebApi()
{
... // do another work
await Task.Factory.StartNew(() => LongWork());
return "ok";
}
2) public async Task<string> WebApi()
{
... // do another work
await Task.Factory.StartNew(async () => await LongWork());
return "ok";
}
3) public async Task<string> WebApi()
{
... // do another work
Task.Factory.StartNew(async () => await LongWork());
return "ok";
}
Run Code Online (Sandbox Code Playgroud)
Q1:方法#1和#2之间有什么区别?
Q2:在ASP.NET世界中,运行方法(在此示例中,LongWork()在后台线程中包含一些异步/等待对的正确方法是什么?特别是在#3中,没有"等待"在Task.Factory.StartNew之前(async()=> await LongWork()).没问题吗?
谢谢!
Ste*_*ary 10
Q1:方法#1和#2之间有什么区别?
#1的开销较小.这是唯一的区别.
Q2:在ASP.NET世界中,运行方法(在此示例中,LongWork()在后台线程中包含一些异步/等待对的正确方法是什么?
您没有提供任何选项.首先,他们都使用Task.Factory.StartNew而没有指定TaskScheduler,这是危险的(正如我在我的博客上所描述的那样).他们应该使用Task.Run.但是,即使您使用Task.Run,也会遇到更严重的潜在问题.
潜在的问题是:HTTP协议以每个请求为中心,只有一个匹配的响应.当HTTP服务器(例如ASP.NET)知道没有未完成的请求时,它会做出"回收工作进程是安全的"这样的假设.
我在博客上更详细地描述了这个问题.此博客文章中还有一种类型BackgroundTaskManager,它使用ASP.NET运行时注册后台任务,并(通过)正确执行它们Task.Run.您应该只BackgroundTaskManager在阅读博客文章时理解并接受这仍然是危险且不安全的.
更好(读取:更可靠)的解决方案是首先写出要对持久存储(例如,Azure队列)执行的工作的表示,并且具有处理请求的独立后端进程(例如,Azure工作者角色).从队列中.
| 归档时间: |
|
| 查看次数: |
4485 次 |
| 最近记录: |