c# - 顶级工作方法中的异步模式

标签 c# multithreading asynchronous task-parallel-library async-await

我们在网络角色中有一些工作线程。它是在 OnStart 方法中创建的

Task.Factory.StartNew(() => DoWorkAsync(), TaskCreationOptions.LongRunning);

然后,DoWorkAsync 方法将继续轮询队列并执行一些耗时的工作。实际工作需要几分钟时间,因为它提交查询作业并等待结果返回。这些函数采用异步模式。实现顶级 DoWorkAsync 方法的正确方法是什么?如果我执行以下操作,那么这里会发生阻塞,并且仅调用一个 PollingQueueAndWorkAsync() 。

public async void DoWorkAsync()
{
  while (_continue)
  {
    await PollingQueueAndWorkAsync();
  }
}

或者下面的?它看起来不正确,因为它一直在不同的线程中运行该方法。

public async void DoWorkAsync()
{
  while (_continue)
  {
    Task.Run(() => PollingQueueAndWorkAsync());
  }
}

我正在尝试将代码重构为“始终异步”。但它应该如何在顶级工作方法中结束呢?

[更新]

尝试更多后,这就是我所拥有的:

public async void DoWorkAsync()
{
  while (_continue)
  {
    Task.Run(async () => await PollingQueueAndWorkAsync());
  }
}

这种行为是我想要的,因为新消息不断添加到队列中,所以这个循环可以处理与队列中的消息一样多的消息。然而,运行一段时间后,它会抛出内存异常。是因为它创建了太多的延续吗?那么我应该使用 SemaphoreSlim 来限制任务数量?

最佳答案

我通常不鼓励在 ASP.NET 中执行与请求无关的代码。但是,如果它是作为独立 worker 仔细编写的(听起来确实如此),那么您可以使用 BackgroundTaskManager type来 self 的博客。

BackgroundTaskManager 理解同步和异步任务,并且这些任务向 ASP.NET 运行时注册,以最大程度地减少回收意外终止它们的可能性。此外,该类型公开了一个名为 BackgroundTaskManager.ShutdownCancellationToken,您的 PollingQueueAndWorkAsync 可以使用它来检测何时应该干净退出。

关于c# - 顶级工作方法中的异步模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19329516/

相关文章:

c# - 为什么我不能在 Unity 中引用对象?

c# - F# 和 WCF 消耗

java - java中同步方法的问题

c# - 读/写锁定 asp.net 中的静态变量

ios - Future 在 Objective-C 中的实现 : unexpected deadlock detected

javascript - 使用 deferred.resolve(value) 返回到我的 .then() 的值未定义

c# - 任务<T>保留启动参数

c# - 修改现有程序以更好地处理异常

javascript - 如何使用 Node 和 TypeScript 获取异步堆栈跟踪?

c# - 如何处理异步函数中的返回值