2016-09-29 16 views
0

私はこれを捜して、C#とWeb Api 2でAsync HTTPリクエストの概念を説明するリンクをいくつか見つけることに成功しました。Web ApiでのAsync 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標準に違反するため、1つのリクエストに対して複数のレスポンスを送信することはできません。しかし、特定のイベントに対して何らかの応答を送るカスタムコードを書くことができます。 Response.Flush() - https://msdn.microsoft.com/en-us/library/system.web.httpresponse.flush(v=vs.110).aspx –

答えて

0

私はあなたのWeb APIメソッドの非同期を作り、この問題を解決することができると思う:

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

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

また、あなたのタスクの呼び出しは、のawaitキーワード、このようなものであるべきあなたは非同期メソッドの中で複数を待つことができます。

この回答が役に立つかどうか教えてください。

+0

私もこれを試してみました。しかし、待っているTask.Run()の実行が終了すると、応答は返されません。応答がすでにTask.Run()が開始される前に送信されていたためです。基本的には、Task.Run()の終了後に実行される必要があるコールバックメソッドが必要です。 –

+0

私はこの非同期的な方法をcalllがたくさんある角度のアプリケーションで使用しましたが、問題はありませんでした。どのようにクライアントからAPIを呼び出すのですか? –

+0

ソリューションを提供するためにシナリオをエミュレートする必要があります。この問題に必要なコードを教えてください。 –

関連する問題