2016-09-29 208 views
0

我已經爲此搜索並設法找到幾個鏈接來解釋C#和Web Api 2中的異步HTTP請求的概念。然而,我沒有得到任何相同的工作示例。Web Api中的異步HTTP請求

爲了清空空氣,我的要求如下。 當客戶端調用一個API(它會執行長時間運行的處理)時,它必須立即返回HTTP 202(Accepted)作爲響應,並在後臺繼續處理。直到現在我清楚了。以下是我如何實施相同的示例代碼。在這個長時間處理任務在後臺完成時,我被卡住的地方必須向同一客戶端發起回調,並返回一個HTTP 200響應。在後臺執行長處理任務時,客戶端可能會發出另一個具有不同值的併發請求。

任何人都可以指向正確的方向。這是可能的只能通過代碼或將有任何設置要在IIS級別實施。感謝你的時間和幫助。

感謝大家提前。

我的代碼到目前爲止。

public HttpResponseMessage Execute(string plugin, string pluginType, string grid, string version) 
    { 
     try 
     { 
      var type = this.LoadPlugin(plugin, pluginType, version); 

      if (type != null) 
      { 
       var method = type.GetMethod("Execute"); 

       if (method != null) 
       { 
        new Task(() => 
        { 
         // This line will take long to execute. 
         var filepath = method.Invoke(Activator.CreateInstance(type), new object[1] { grid }); 

         // After this line it must invoke a callback to the client with the response as "filepath" and HTTP status code as 200 
         type = null;        
        }).Start(); 
       } 
       else 
       { 
        return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable); 
       } 
      } 
      else 
      { 
       return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable); 
      } 
     } 
     catch (Exception ex) 
     { 
      return new HttpResponseMessage(HttpStatusCode.InternalServerError); 
     } 

     return new HttpResponseMessage(HttpStatusCode.Accepted); 
    } 

    private Type LoadPlugin(string plugin, string pluginType, string version) 
    { 
     Assembly assembly; 

     Type returnValue = null; 

     var pluginFile = new DirectoryInfo(this._pluginPath).GetFiles("*.dll") 
                  .Where(file => FileVersionInfo.GetVersionInfo(file.FullName).OriginalFilename.ToUpper().Contains("TRANSFORMATION." + plugin.ToUpper())) 
                  .OrderByDescending(time => time.LastWriteTime).FirstOrDefault(); 

     if (pluginFile != null) 
     { 
      assembly = Assembly.LoadFrom(pluginFile.FullName); 

      AppDomain.CurrentDomain.Load(assembly.GetName()); 

      returnValue = assembly.GetType("Transformation.Plugins." + pluginType); 

      assembly = null; 
     } 

     return returnValue; 
    } 
+0

您無法爲單個請求發送多個響應,因爲它會違反HTTP標準。但是,您可以編寫自定義代碼來針對特定事件發送一些響應。你也可以考慮Response.Flush() - https://msdn.microsoft.com/en-us/library/system.web.httpresponse.flush(v=vs.110).aspx –

回答

0

我認爲你可以解決這個問題,使您的Web API方法異步:

public async Task<HttpResponseMessage> Execute(string plugin, string pluginType, string grid, string version) 
{ 
    // Your code here 
} 

而且,你的任務的invoke應符合的await關鍵字,像這樣:

await Task.Run(() => 
{ 
    // Yor code here 
}); 

你可以有多個等待你的異步方法。

讓我知道這個答案是否有用。

+0

我也試過這個。但在等待Task.Run()完成執行後,它不會返回響應;因爲響應已經在Task.Run()開始之前發送了。所以基本上,必須有一個回調方法,必須在Task.Run()完成後執行。 –

+0

我已經使用這種異步方式與角應用與很多callls,我沒有麻煩,你如何從客戶端調用你的API? –

+0

我需要模擬您的方案以提供解決方案,您能否爲我提供此問題所需的代碼? –