2016-04-27 88 views
1

我上,要求以下邏輯的web服務工作:從WebApi返回HTTP響應後可以執行代碼嗎?

  1. 接收請求
  2. 登錄請求
  3. 迴應說請求被接收
  4. 過程請求(解析和運行邏輯)

原因是這條消息的經紀人不想等我們完成我們的(可能是「長時間運行」; < 10秒可能是< 1s)邏輯知道我們已收到請求之前。

我看到的一個選擇是簡單地寫入日誌並返回,並讓定時作業處理來自日誌的消息,但這看起來過多(儘管我們打算將此作爲備份來實現)。

我的工作解決方案是在傳遞消息的消息處理程序中產生一個Task,但我對線程知之甚少,無法知道離開一個孤立的Task可能會產生什麼問題。這裏是所述的解決方案:

public class LoggingHandler : DelegatingHandler 
{ 

    protected async override Task<HttpResponseMessage> SendAsync(
     HttpRequestMessage request, 
     CancellationToken cancellationToken) 
    { 

     string content = await request.Content.ReadAsStringAsync(); 
     HttpRequestHeaders header = request.Headers; 
     HttpMethod method = request.Method; 
     Uri uri = request.RequestUri; 
     Version version = request.Version; 
     IDictionary<string, object> properties = request.Properties; 

     // Reset content. This might not be necessary, but due to the fact 
     // HttpRequestMessage.Content is only meant to be read once it's 
     // here to be safe. 
     request.Content = new StringContent(content); 

     bool messageLogged = true; 
     // Write content to message table 
     if (!messageLogged) 
     { 
      return new HttpResponseMessage(
       System.Net.HttpStatusCode.InternalServerError); 
     } 

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed 
     Task.Run(() => 
     { 
      try 
      { 
       base.SendAsync(request, cancellationToken).Wait(); 
      } 
      catch (Exception) 
      { 

      } 
     }); 
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed 

     return new HttpResponseMessage(System.Net.HttpStatusCode.OK); 
    } 
} 

這是否像我這樣可怕? Task.Run(..)可以拋出一個異常(內存不足,等等?),會導致什麼結果?我會遇到線程池的問題嗎?

總之,有沒有適當的解決這個問題?

+0

因爲你抓在任務異常。運行,沒有什麼會出問題的,唯一的問題是看到你可以對任何請求你的人撒謊,因爲任務內的代碼可能有錯誤,並且你返回OK。 –

回答

2

這是一個我認爲的建築問題。

我會考慮對長時間運行的任務使用消息隊列。它可能是最簡單形式的內存中實現。您始終可以編寫一些邏輯來重試消息並更新日誌/表中消息項的狀態。

但是,如果你想要更強大的消息處理,我寧願使用消息代理,如RabbitMQ,Azure服務總線等等。它們爲您提供消息彈性,並使您能夠使用各種模式來實現消息的處理方式。

所以我的建議是對於長時間運行的任務:

  1. 接收請求
  2. 登錄請求
  3. 傳遞消息到消息代理(用於分析和邏輯) - 不要等待它。
  4. 迴應說,收到請求
  5. 做點從客戶端其他跟進的消息以後(事件的WebSocket,輪詢++)
+1

我同意並建議您查看[HangFire](http://hangfire.io/),它可以幫助您輕鬆創建這樣的應用程序。 –

相關問題