在我的 .NET7 ASP.NET 服务器中,我使用此代码在应用程序的生命周期内进行一些后台处理。
_ = Task.Run(async () =>
{
while (true)
{
try
{
if (isDataAvalibale) await DoDBBoundProcessing();
await Task.Delay(10);
}
catch (Exception ex)
{
Log.Write("", $"Background error: {ex.Message}");
}
}
}
然后我还有另一个用于 CPUBoundProcessing 的。处理功能必须连续重复。
第一个将数据从 ConcurrentQueue 序列化到数据库,另一个对内存对象进行一些处理。
Task.Run 可以工作,从来没有任何问题,但我知道这不是处理后台处理的最佳方法。
我读过大卫·福勒的这篇文章:
https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#avoid-using-taskrun-for-long-running-work-that-blocks-the-thread
建议使用:
var thread = new Thread(ProcessQueue)
{
// This is important as it allows the process to exit while this thread is running
IsBackground = true
};
thread.Start();
或
Task.Factory.StartNew(ProcessQueue, TaskCreationOptions.LongRunning);
但我不明白哪一个更适合我的用例。 然后是“带有托管服务的后台任务”选项。
我想让事情尽可能简单,就可靠性而言,我当前的 Task.Run 还可以:
我只想正确管理线程/任务资源。
我的用例的正确方法是什么?
CPU 绑定和 I/O 绑定操作应该有所不同吗?
谢谢
您不需要同时使用这两种方法,因为线程池线程将执行您的代码,直到等待任务。延迟代码将返回到池中。10 毫秒后,线程池中的另一个线程将继续执行它离开的位置。 但是您应该处理 asp.net 重新启动事件,因此使用 托管服务 将您的代码(启动您的任务。但不返回该任务)放入 StartAsync 中,并检查循环中的取消令牌。