2016-09-29 210 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

我需要模拟您的方案以提供解决方案,您能否为我提供此问题所需的代码? –