与线程的异步Rest API调用会影响性能吗?

时间:2016-02-12 06:44:07

标签: c# multithreading asynchronous

所以我的一位同事对我说 -

  

“为什么有人想用线程调用异步RestAPI,它没有用处,反过来它会为每个请求创建一个单独的线程。”

我的情景是 -

public async Task<ApiResponse<ProductLookupDto>> GetProductsByValueOfTheDay()
{
    string url = "http://domain.com?param=10120&isBasic=true"
    var result = Task.Run(() => JsonConvert.DeserializeObject<ProductLookupDto>(SerializedResults.GET(url)));
    return new ApiResponse<ProductLookupDto>()
    {
        Data = await result,
        Message = "success"
    };
}

所以我在这里使用线程异步。我知道它会为请求创建一个单独的线程。这是我对性能的关注。

我想知道我的某些方法是否被一起调用,并且响应是否像我现在所做的那样异步。线程会影响性能吗? 请记住 - 来自其他来电的响应太强了。

2 个答案:

答案 0 :(得分:3)

你的朋友实际上并不是真的知道他在说什么 - 任务不会为每个请求创建一个单独的线程。相反,任务调度程序将确定线程 - 标准使用线程池。这意味着线程已预先分配和重用,特别是如果您安排了大量任务。由于完成端口,请求在运行时释放线程。你的同事在这里表现出严重缺乏基础知识。

答案 1 :(得分:0)

我认为你的同事关心那段代码是正确的,你说“它假装是异步但不是真的”是对的。并且Jon Skeet指出,真正的问题在于levelItemKeys。无论具体是什么实现,它显然是一个阻塞调用,否则它将返回SerializedResults.GET(可以是Task<string> ed)而不是字符串。在await中包装同步调用并将其称为异步是一个常见的错误。你根本没有消除阻塞,你只是将阻塞调用移动到另一个线程。

为了使这个异步,Task.Run需要去。它应该被一个使用真正异步库(如HttpClient)的调用所取代。由于这是一个JSON API(我有点偏颇),我将向您展示一个使用我的Flurl库的示例,它基本上是HttpClient和Json.NET的包装器,提供了一些方便的方法。减少噪音:

SerializedResults.GET