问题描述
让我们假设我有一个需要相当长的时间,直到完成其工作如下异步方法:
无效异步任务LongWork()
{
等待LONGWORK()// ...长时间工作
}
现在,在网页API,我想运行在后台的工作(即我想在开始后返回HTTP请求的LongWork(),但其完成前:
我能想到的三种方法来实现这一点:
1)公共异步任务<串GT;的WebAPI()
{
... //做的另一项工作 等待Task.Factory.StartNew(()=> LongWork()); 返回确定;
}
2)公共异步任务<串GT;的WebAPI()
{
... //做的另一项工作 等待Task.Factory.StartNew(异步()=>等待LongWork()); 返回确定;
}3)公共异步任务<串GT;的WebAPI()
{
... //做的另一项工作 Task.Factory.StartNew(异步()=>等待LongWork()); 返回确定;
}
Q1:什么是方法#1和#2之间的区别
Q2:什么是在ASP.NET的世界,运行一个方法(在这个例子中,正确的方式,包含了一些异步LongWork()/等待对在后台线程?
特别是,在#3,有没有等待Task.Factory.StartNew之前(异步()=>等待LongWork())。难道是罚款?
谢谢!
#1 has less overhead. That is the only difference.
None of the options you provided. For one thing, they all use Task.Factory.StartNew
without specifying a TaskScheduler
, which is dangerous (as I describe on my blog). They should use Task.Run
instead. However, even if you use Task.Run
, you will run into a more serious underlying problem.
The underlying problem is this: the HTTP protocol is centered around each request having exactly one matching response. When an HTTP server (such as ASP.NET) knows that there are no outstanding requests, it will make assumptions like "it's safe to recycle the worker process".
I describe this problem in more detail on my blog. Also in that blog post is a type BackgroundTaskManager
that registers background tasks with the ASP.NET runtime and (correctly) executes them via Task.Run
. You should only use BackgroundTaskManager
if you read the blog post and understand and accept that this is still dangerous and unsafe.
A far better (read: more reliable) solution is to first write out a representation of the work to be done to persistent storage (e.g., an Azure queue) and have an independent backend process (e.g., an Azure worker role) that processes requests from the queue.
这篇关于异步/等待在ASP.NET的WebAPI背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!