【问题标题】:How to check if Task thread is blocked如何检查任务线程是否被阻塞
【发布时间】:2016-12-20 23:41:54
【问题描述】:

我有一个运行到瓶颈的 WebAPI 网络服务,每当有许多请求获得一个长时间运行的数据库操作时,所有其他请求都需要比正常时间更长的时间才能完成。

网络服务的每个端点如下:

            var result = await Task.Run(() =>
            {
                return _coordinator.GetValue(key);
            });

            return Request.CreateResponse(HttpStatusCode.OK, result);

其中 _coordinator 是通过构造函数注入的类,它将调用将从数据库中获取数据的服务(非 Web 服务)(长时间运行)。 _coordinator 可能会调用几个长时间运行的服务调用,这些调用又会从数据库中获取。

据我了解,Task.Run 将创建一个任务,该任务将在线程池中的一个线程中运行。但我不确定这些线程是否在可以被释放时被阻塞。

所以我想让线程运行协调器代码,看看它是否被阻塞或是否被释放到线程池,直到机器服务返回。

【问题讨论】:

  • 线程是一种充足的资源。您不太可能受到线程数量的限制。听起来您的数据库只是过载了。优化查询。
  • _coordiantor 是第三方还是您自己的?
  • _coordinator 是我们自己的类。这是一个穿越。它调用中间件服务从 Oracle DB 中获取。
  • GetValue() 是异步的吗?换句话说,它的返回类型是什么?
  • @svick,它不是异步的,它从数据库返回一个数据模型。我们谈论的是数千个并发连接。

标签: c# multithreading asp.net-web-api task-parallel-library


【解决方案1】:

由于GetValue()是同步方法,所以Task.Run()使用的ThreadPool线程将在方法执行的整个过程中使用。

如果您担心您的代码使用的线程数(并且因为您说您可以有许多并发请求,这是一个有效的担心),那么您应该使 GetValue() 真正异步。为此,您需要异步调用服务。具体如何执行取决于您如何调用服务,但通常涉及将foo.Bar() 更改为await foo.BarAsync()


另外,由于您的代码是一个 web 服务,它已经在一个 ThreadPool 线程上运行,没有理由使用 Task.Run() 切换到另一个线程(然后使用 await 释放第一个线程)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2012-01-27
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    相关资源
    最近更新 更多