在我的.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。Processing函数必须不断重复。
第一个将数据从ConcurrentQueue序列化到DB,另一个对内存对象进行一些处理。
运行任务工作,从来没有任何问题,但我知道这不是最好的方式来处理后台处理。
我从大卫福勒那里读到:
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);
型
但是我不明白哪一个更适合我的用例。然后是“托管服务的后台任务”选项。
我想让事情尽可能简单,在可靠性方面,我目前的任务。运行是可以的:
- 如果服务器停止,后台进程停止,
- 如果由于某种原因,一个处理过程创建了一个异常并重新启动,
我只想正确管理线程/任务资源。
对于我的用例,正确的方法是什么?
CPU绑定操作和I/O绑定操作是否应该不同?
谢谢
1条答案
按热度按时间q3qa4bjr1#
你不需要这两种方法,因为线程池线程将执行你的代码,直到await task.delay code比将返回到池。10毫秒后,线程池中的另一个线程将继续执行它离开的地方。但你应该处理asp.net重新启动事件,所以使用Hosted service把你的代码(启动你的任务。但不返回该任务)放在StartAsync中,并在你的循环中检查取消令牌。