检查使用 Task.Run 调用的线程的状态

Check the status of a thread which calls using Task.Run

我正在尝试检查循环运行的异步任务的状态。

这是我的代码的样子

for(i=0;i<10;i++)
{
    Task t=Task.Run(()=>MyLongRunningTask(params));
   /// Feeding Task.Id
}

我在这里输入任务 ID。 但我的问题是有什么方法可以使用我们存储的 ID 来查找任务的状态

例如,我正在调用带有长 运行 任务的 API,API 调用 Task.Run,由于它是异步的,所以我返回 202。

来自另一个 API,我想要实现的是检查该循环中上述记录线程的状态。

如何实现。

另外我有点困惑为什么它的警告添加等待。当我添加 await 时,它将等待进程完成,并且只有在进程完成时才返回数据。但是那个时候,它不是异步的,不是吗?那么为什么到处都说在调用 task.run

之前添加 Await

But my question is there is any way to find the status of a Task using the ID we stored

没有。给定一个 id,你不能查找 Task 对象。您需要自己将它们存储在像 ConcurrentDictionary 这样的线程安全字典中,并且一定要记得在它们完成时从字典中清除它们,否则您最终会导致资源泄漏。

For example I am calling an API with long running task, the API calls the Task.Run and since its async, I am returning 202.

这是一个极其危险的解决方案。它有几个问题:

  1. 由于工作完全在内存中(在线程池工作队列中),只要重新启动服务器、重新启动托管应用程序或回收应用程序池,工作就会丢失。两种常见情况是部署代码更新或应用 OS 补丁;这些中的任何一个都可能导致您失去工作。
  2. 由于 id-to-status 查找也在内存中,任何状态检查API调用都需要命中相同的实例 作为开始工作的 API 调用。在服务器场中通常不会出现这种情况。

How to achieve that.

异步消息传递唯一真正的解决方案是 basic distributed architecture:

  1. 持久队列,即内存中。
  2. 处​​理队列的后端服务。此 可以 托管在与 Web 服务相同的应用程序中,但我通常建议将其作为一个独立的进程。
  3. tracking/retrieving 结果的系统。这可以是持久的或在某些(分布式)内存中,如 Redis。

But that time, its not async, isnt it? So why everywhere saying to add Await before calling a task.run

这是因为这里的“异步”有两种不同的含义。 “异步”可以表示“让出当前线程”。它在更高层次上也可能意味着不同的东西;在这种情况下,它可能意味着“调用 API 开始操作”——通常称为“异步消息传递”。

当在 ASP.NET 上使用 async/await 关键字时,他们 are "asynchronous" in the sense that they allow the request thread to return to the thread pool. They are not "asynchronous" 在某种意义上说他们 return 早给客户。