2014-01-21 80 views
1

我有一个web api调用,我想获得巨大的吞吐量,所以我用一个任务包装I/O,希望使其异步。但是,我不确定它确实希望我寻找。C#封装io与任务,使异步

public HttpResponseMessage Post([FromBody]DataRequest request) 
    { 
     Task.Factory.StartNew(() => 
     { 
      service.SendRequestToQueue(request); 
     }); 

     return Request.CreateResponse(HttpStatusCode.Accepted); 
    } 

我觉得这不是正确的做法。它确实使I/O脱离了请求线程,但仍由应用程序中的线程处理,而不是由内核处理。我对吗?有没有更好的方法来做到这一点,然后做出异步并一直等待?

+2

不是。您通常应该完全同步,或完全异步。异步异步(这是什么)或通过异步同步(异步操作同步阻塞)都是非常有问题的,应该尽可能避免成本。 – Servy

+0

究竟是什么原因呢?它看起来像客户只是发送请求,而不是等待结果?如果是这种情况,那么这是一种很好的方法。 我不确定为什么塞维认为你应该不惜一切代价避免异步方法。这似乎不是一个合理的话。显然,如果你要开始异步工作,你将会公开一组新的prooblems,但是异步等待可用是有原因的。如果你的意图是击中它并忘记它,那么这是一个很好的解决方案。但是如果你需要等待一个结果。只需使用异步等待。 – Callan

+0

@Callan:这不是一个好的解决方案; [这是非常危险的](http://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html),正如我在我的博客上解释的。 –

回答

1

正如@Servy所评论的,正确的解决方案是一直使用async。特别是在ASP.NET上,您应该避免使用Task.RunTask.Factory.StartNew。如您所怀疑的,使用await以及排队等待线程池的任务不会给您带来任何可伸缩性优势。

您当前的代码将返回响应,同时继续处理内存中的请求。这是非常危险的,因为我解释了on my blogin a recent CodeMash talk(参见题为“早期回归”的“Gotchas”部分下的幻灯片)。