呼叫任务.delay(50)经常在循环中。这会导致内存泄漏吗?

发布于 2025-02-10 04:25:54 字数 1772 浏览 3 评论 0原文

总之。 我有ASP.NET Core 6 REST API项目,其背景服务每50 ms执行一些工作。例如:

public class DemoWorker : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // Do work
            Console.WriteLine(DateTimeOffset.Now);
            await Task.Delay(50, stoppingToken);
        }
    }
}

最近,我注意到了Resmanter Dynamic计划分析(DPA)工作人员报告的以下问题。

小物体堆:分配8.1 MB(8500792 B),最大:100.2 MB (105041568 b)类型系统。 demoworker.executeasync(concellationToken)

在system.threading.tasks.task.delay(uint,cancellationToken)at system.threading.tasks.task.delay(timespan,concellationToken)at demoworker.executeasync(cancellationToken)in< source_code_file_name> 在system.threading.executioncontext.runinternal(executionContext, contextCallback,对象) system.runtime.compilerservices.asynctaskmethodbuilder 1+asyncstatemachinebox 1< system .__佳能,startuphook,startuphook+d__3> .movenext(thread) 在 system.threading.tasks.awaittaskContination.runorscheduleaction(iaSyncstatemachinebox, bool)at system.threading.tasks.task.task.runco​​ntinuations(对象)at system.threading.tasks.task.trysetresult()at system.threading.tasks.task+delaypromise.completeTimedOut()at system.threading.timerqueuetimer.fire(bool)at system.threading.timerqueue.firenexttimers()at system.threading.unmanagedthreadpoolworkitem.system.threading.ithreadpoolworkitem.execute() at System.Threading.threadPoolworkqueue.dispatch()at system.threading.portablethreadpool+workerthread.workerthreadstart()

我阅读了几篇文章。他们中的大多数人说这不是问题,我不需要做任何特别的事情或处理任务。

但是其中一篇文章说,如果我要创建task.delay()呼叫速度要比结局快,那么我将有一个内存泄漏!

所以我的问题是我应该为此担心还是只是忽略它?

In summary.
I have ASP.NET Core 6 Rest API project with a BackgroundService that is performing some work every 50 ms. For example:

public class DemoWorker : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // Do work
            Console.WriteLine(DateTimeOffset.Now);
            await Task.Delay(50, stoppingToken);
        }
    }
}

Recently, I noted the following issue reported by the ReSharper Dynamic Program Analysis (DPA) worker.

Small Object Heap: Allocated 8.1 MB (8500792 B), max: 100.2 MB
(105041568 B) of type System.Threading.TimerQueueTimer by
DemoWorker.ExecuteAsync(CancellationToken)

at System.Threading.Tasks.Task.Delay(uint, CancellationToken) at
System.Threading.Tasks.Task.Delay(TimeSpan, CancellationToken) at
DemoWorker.ExecuteAsync(CancellationToken) in <SOURCE_CODE_FILE_NAME>
at System.Threading.ExecutionContext.RunInternal(ExecutionContext,
ContextCallback, Object) at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder1+AsyncStateMachineBox1<System.__Canon,StartupHook+d__3>.MoveNext(Thread)
at
System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox,
bool) at System.Threading.Tasks.Task.RunContinuations(Object) at
System.Threading.Tasks.Task.TrySetResult() at
System.Threading.Tasks.Task+DelayPromise.CompleteTimedOut() at
System.Threading.TimerQueueTimer.Fire(bool) at
System.Threading.TimerQueue.FireNextTimers() at
System.Threading.UnmanagedThreadPoolWorkItem.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch() at
System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()

I read several articles on this. Most of them are saying that this is not a problem and I don't need to do anything special, or to dispose the task.

But one of the articles says that If I'm creating Task.Delay() calls faster than they're ending, then I will have a memory leak!

So my question is should I worry about this or just ignore it ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

聚集的泪 2025-02-17 04:25:54

有一个用于此目的的课程,您也可以使用。

var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(50));

while (await timer.WaitForNextTickAsync(stoppingToken))
{
    // Do work
    Console.WriteLine(DateTimeOffset.Now);
}

但是,由于操作系统的体系结构,与时间相关的任务不是%100可靠。

https:https:// wwwwww .c-sharpcorner.com/article/comparison-of-microsoft-windows-tools-for-waiting-time-management/

There is a class for this purpose you can use as well.

var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(50));

while (await timer.WaitForNextTickAsync(stoppingToken))
{
    // Do work
    Console.WriteLine(DateTimeOffset.Now);
}

But due to the operating system's architecture, time-related tasks are not %100 reliable.

https://www.c-sharpcorner.com/article/comparison-of-microsoft-windows-tools-for-waiting-time-management/

屋顶上的小猫咪 2025-02-17 04:25:54

不,这种使用模式应导致任何内存泄漏。 task task.delay 方法,其所有内部部件应有资格在任务完成后立即获得垃圾收集。没有什么可以使垃圾收集器无法回收这些物体。

如果您发现timerqueuetimer对象有多个随后的垃圾收集的对象,那么您可能已经在.NET标准库中找到了一个错误。

No, this pattern of usage should not cause any memory leak. The Task object created by the Task.Delay method, and all of its internal parts, should be eligible for garbage collection immediately after the completion of the task. There should be nothing that holds the garbage collector from recycling those objects.

In case you find that there is an unusually high number of TimerQueueTimer objects that are surviving multiple subsequent garbage collections, you might have found a bug in the .NET standard libraries.

心作怪 2025-02-17 04:25:54

建议:我可能宁愿使用新的preseictimer,因为应该根据此文章

Suggestion: I might rather use the new PeriodicTimer as it should be memory leak resistant according to this article.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文