我有一个运行到瓶颈的WebAPI Web服务,每当有多个请求获得一个长时间运行的数据库操作时,所有其他请求都需要比正常情况更长的时间才能完成。
webservice的每个端点如下:
var result = await Task.Run(() =>
{
return _coordinator.GetValue(key);
});
return Request.CreateResponse(HttpStatusCode.OK, result);
其中_coordinator是通过Constructor注入的类,它将调用将从数据库中获取数据的服务(非Web服务)(长时间运行)。 _coordinator可能会调用多个长时间运行的服务调用,而这些调用又将从数据库中获取。
根据我的理解,Task.Run将创建一个将在线程池中的线程中运行的任务。但我不确定这些线程是否可以在被释放时被阻止。
所以我想让线程运行协调器代码,看它是否被阻塞,或者它是否被释放到线程池,直到机器服务返回。
答案 0 :(得分:2)
由于GetValue()
是同步方法,Task.Run()
使用的ThreadPool线程将在方法执行的整个时间内使用。
如果您担心代码使用的线程数(并且因为您说您可以有许多并发请求,这是一个有效的担心),那么您应该使GetValue()
真正异步。为此,您需要异步调用服务。具体如何取决于您如何调用该服务,但通常涉及将foo.Bar()
更改为await foo.BarAsync()
。
此外,由于您的代码是Web服务,它已经在ThreadPool线程上运行,因此没有理由使用Task.Run()
切换到另一个线程(然后使用await
来发布第一个)。