【问题标题】:How to avoid OutOfMemoryException when using Task.Run()? [duplicate]使用 Task.Run() 时如何避免 OutOfMemoryException? [复制]
【发布时间】:2020-12-28 10:58:46
【问题描述】:

当我在启动时调用此方法时出现 OutOfMemoryException。 StartSignalR 方法应该运行一个每秒调用 Update() 方法的任务。

  public void StartSignalR()

    {

        Task t = Task.Run(() =>
        {
            try
            {
                bool push = true;
                while (push)
                {
                    Update();
                }
            }
            catch (System.Exception ex)
            {
                LogManager.LogError(ex);
            }
        });
    }

我在 Update() 中使用 Task.Delay

 private async static void Update()
    {
        await Task.Delay(1000);
        
        Updater.MPrice();
    }

【问题讨论】:

  • Task.Run 肯定不会导致 OOM 异常。你需要查看和调试你的代码,你在某处有内存泄漏
  • @CamiloTerevinto 如果我不调用此方法,则不会发生 OOM
  • 您可能每秒调用Update() 数百万次,因此Updater.MPrice() 中的任何内容都会在某处泄漏内存,或者创建足够大的对象以使您的系统内存不足。您需要await 拨打Update
  • 请分享minimal reproducible example,包括MPrice的源代码。
  • 另外,您忘记在Update 上调用awaitUpdate 应该返回Task 而不是void

标签: c# multithreading task


【解决方案1】:

要让您的 Task.Delay 真正等待,您必须将您的 lambda 声明为 asyncawait Update 方法。

public void StartSignalR()
{
    //added async
    Task t = Task.Run(async () =>
    {
        try
        {
            bool push = true;
            while (push)
            {
                //await the Update method
                await Update();
            }
        }
        catch (System.Exception ex)
        {
            LogManager.LogError(ex);
        }
    });
}

通过此更改,您的 Update 方法必须返回 Task

//changed signature
private async static Task Update()

这很有可能会减少内存占用,因为目前您正在疯狂地触发 Update 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 2013-04-29
    • 1970-01-01
    相关资源
    最近更新 更多