2014-09-29 27 views
1

所以我想使用HTTP 202代碼創建理念,爲服務器端非同步的證明(服務器接受任務後,立即返回終點輪詢,然後創建/更新資源)我如何產生一個將完成並立即返回給客戶端的任務?

Rick Strahl has a description如何在普通的ASP.NET中做到這一點。該技術取決於能夠Response.End,然後繼續執行代碼。 Response對象甚至似乎在Web API控制器的上下文中不可用。

如果以下工作按計劃進行,它不會阻止返回http 202並仍然保證數據庫任務將運行完成。

//Insert or Update Asych. 
public Task<HttpResponseMessage> Post(bool asynch, [FromBody]DatedValue value) //Insert Value 
{ 
    Guid key = Guid.NewGuid(); 

    //Want this to run to completion, even if response associated with parent thread is done. 
    Task toWait = Task.Factory.StartNew(() => 
    { 
     queue.Add(key, 0); 
     DatedValue justCreated = Insert(value); 
     queue[key] = justCreated.Id; 
    }); 

    //Return address to resource just created. 
    Task<HttpResponseMessage> sender = Task.Factory.StartNew(() => 
    { 
     HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.Accepted); 
     message.Headers.Location = new Uri("/ValueQueue/" + key); 
     return message; 
    }); 

    Task.WaitAll((new[] { toWait, sender })); 

    return sender; 
} 
+1

你的問題是什麼?爲我測試?寫另一個? – 2014-09-29 22:18:50

+0

如何生成一個將完成並立即返回(響應)到客戶端的任務?英文模式的簡短描述應該沒問題。我實際上並不信任多線程代碼的測試,但nunit主機不像ASP.NET主機。 – MatthewMartin 2014-09-30 00:20:06

+1

你的代碼不會實現你的目標。你在'Task.WaitAll'上阻塞,所以你的方法不能完成,直到*任務完成。你真正想要的東西是你的「之後」邏輯的一個難忘的(未被察覺的)任務,但是ASP.NET如何對待即忘即滅的任務,以及它是否會保證它們將運行完成即使在發佈響應之後 - 我不知道(更不用說這聽起來像是一個非常糟糕的主意)。 – 2014-09-30 03:43:18

回答

3

Task.WaitAll塊執行和響應直到兩個任務完成後才返回。如果您更改您的代碼,如下所示,您應該能夠在任務運行時返回響應。

public HttpResponseMessage Post(bool asynch, [FromBody]DatedValue value) 
{ 
    Guid key = Guid.NewGuid(); 

    Task.Factory.StartNew(() => 
    { 
     queue.Add(key, 0); 
     DatedValue justCreated = Insert(value); 
     queue[key] = justCreated.Id; 
    }); 

    HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.Accepted); 
    message.Headers.Location = new Uri("/ValueQueue/" + key); 
    return message; 
} 

但是,您應該意識到像這樣的方法的問題。如果您在IIS上託管Web API,則您的工作進程可以在任務運行時得到回收。由於你已經返回了響應,就ASP.NET而言,它已經完成了它的工作。所以,如果由於某種原因IIS決定回收工作進程,它將繼續前進,無論您的任務在執行方面如何,因此最終可能會導致數據損壞。

使用.NET 4.5.2,您可以使用QueueBackgroundWorkItem。閱讀 - http://blogs.msdn.com/b/webdev/archive/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-long-background-process-in-asp-net.aspx

相關問題