1

通常は非同期の ApiController から「即時」の応答を返すことに問題があります。コードは以下のとおりで、感嘆符を探します。ユースケースは、コンテンツ タイプ チェックが失敗し、エラー応答メッセージを送り返したい場合です。最初のバージョンでは、Visual Studio 2010 (および Fiddler) がハングします。2番目の作品。

私の質問は、応答オブジェクトを返すだけのダミー Task を返すという最初のアプローチを使用できないのはなぜですか?

public class MyController : ApiController
{

   public Task<HttpResponseMessage> Post([FromUri]string arg)
   {
       HttpResponseMessage response = null;

       // synchronous validation
       if (Request.Content.Headers.ContentType.MediaType != @"image/jpeg")
       {                    
           response = Request.CreateErrorResponse(
               HttpStatusCode.UnsupportedMediaType,
               "Invalid Content-Type.");
       }


       if (response == null)  // no immediate response, switch to async
       {
          // work done here    
       }
       else // immediate response, but we need to wrap in a task for caller to fetch
       {

           // !!!! this one doesn't work !!!
           return new Task<HttpResponseMessage>( () => response);

           // !!! this one does !!!
           TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
           tcs.SetResult(response); 
           return tcs.Task;

       }
    }
}
4

1 に答える 1

8

のコンストラクターはTask<T>、まだ開始されていないタスクを返します。それが機能するには、次のようなことを行う必要があります。

var task = new Task<HttpResponseMessage>(() => response);
task.Start();
return task;

ただし、ラムダがスレッドプールで不必要に実行されるため、これを行うのは非効率的です。2番目のバージョンの方が優れており、.Net 4.5ではさらに優れたバージョンを使用することもできますTask.FromResult()

return Task.FromResult(response);
于 2012-10-23T22:33:40.217 に答える