C#使用任务包装阻塞io以使其异步

C#使用任务包装阻塞io以使其异步,c#,multithreading,asynchronous,io,task-parallel-library,C#,Multithreading,Asynchronous,Io,Task Parallel Library,我有一个web api调用,我希望获得更大的吞吐量,因此我用一个任务包装I/O,希望使其异步。然而,我不确定它是否需要我寻找 public HttpResponseMessage Post([FromBody]DataRequest request) { Task.Factory.StartNew(() => { service.SendRequestToQueue(request); });

我有一个web api调用,我希望获得更大的吞吐量,因此我用一个任务包装I/O,希望使其异步。然而,我不确定它是否需要我寻找

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

        return Request.CreateResponse(HttpStatusCode.Accepted);
    }

我觉得这样做不对。它确实从请求线程获取I/O,但仍然由应用程序中的线程而不是内核处理。我说得对吗?除了异步并一直等待之外,还有更好的方法吗?

正如@Servy所评论的,正确的解决方案是一直使用
async
。特别是在ASP.NET上,您应该避免使用
Task.Run
Task.Factory.StartNew
。正如您所怀疑的那样,使用
wait
将任务排入线程池队列将不会给您带来任何可伸缩性好处


当前的代码返回响应,同时继续在内存中处理请求。正如我所解释的那样,这是非常危险的(请参阅“早退”部分下的幻灯片)。

不太危险。您通常应该是完全同步的,或者完全异步的。Async over sync(就是这样)或sync over Async(异步操作上的同步阻塞)都是非常有问题的,应该不惜一切代价加以避免。具体原因是什么?看起来客户端只是发送请求,而不是等待结果?如果是这样的话,那么这是一个很好的方法。我不知道为什么Servy认为应该不惜一切代价避免异步方法。这似乎不是一个合理的说法。显然,如果您要开始异步工作,您将公开一组新的问题,但是异步等待是有原因的。如果你的目的是击中它,然后忘记它,那么这是一个很好的解决方案。但如果你需要等待结果。使用async await即可。@Callan:这不是一个好的解决方案,正如我在博客上解释的那样,我认为这是一篇优秀的博客文章。我只是假设他不在乎结果如何。在子线程中抛出一个异常可以关闭应用程序池,但是有了正确的异常处理,他就不必担心了。当然,在绝大多数情况下,您需要等待结果,创建子线程并等待它返回是毫无意义的。但是在关闭更改时,他真的不关心返回的内容,这将是一种可行的方式,将工作发送到服务器并将其忘记。但我同意,这方面的用例很少。