C# Приложение занимает много времени, чтобы вернуться из сна после большого времени безотказной работы - PullRequest
0 голосов
/ 11 марта 2020

У меня есть приложение C#, которое запускает несколько потоков, которые выглядят следующим образом.

public void Update()
{
    long UpdateInterval = 50;

    while (_running)
    {
        long start = TimeMgr.Milliseconds();

        if (start - _updateFinished > 200)
            _logger.Warn("waking up from sleep too long - took {Time} ms. Thread ID: {Thread}", (start - _updateFinished), _threadId);


        UpdateLogic();

       _updateFinished = TimeMgr.Milliseconds();

       long elapsed = _updateFinished - start;


       if (elapsed < UpdateInterval)
          Thread.Sleep((int)(UpdateInterval - elapsed));
       else
       {
           if (elapsed > 200)
              _logger.Warn("update took too long. {Time}ms. Thread ID: {Thread}", elapsed, _threadId);

       }
    }
}

Однако после 24 ч + запуска сообщение «просыпаться из спящего слишком долго» начинает срабатывать, показывая, что Это занимает 300 мс, для большинства потоков каждые 5-10 секунд. Я предположил, что это может быть сборщик мусора, поэтому мы переключились на gcServer = true, после чего приложение использует больше памяти, однако все еще доступно <40%, прежде чем эта проблема снова запустится через ~ 24 часа. </p>

Запуск показов dotTrace что приложение проводит большую часть времени в спящем режиме, что следует ожидать при низкой нагрузке.

https://i.imgur.com/KG7RjJj.png

Ранее эта проблема работала на Windows 10 с использованием gcServer = true, когда приложение набирало до 95% использования оперативной памяти, мы переключились на gcServer = false, что, похоже, решило проблему.

Однако после перехода на наш новый компьютер с Windows Sever 2019 В общем, эта проблема, похоже, снова обострилась, и изменение этого значения, похоже, не имеет никакого эффекта, иначе задержка этого эффекта с 20% использования памяти до 30% использования памяти.

Наши текущие настройки app.config установлены на

<?xml version="1.0"?>
<configuration>
  <runtime>
    <gcServer enabled="true"/>
    <gcConcurrent enabled="true"/>
  </runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>

и мы изначально устанавливаем это при запуске приложения

GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;

В идеале мы бы хотели, чтобы сборка мусора занимала минимум количество времени возможно. На сервере выделено 64 ГБ памяти, и я рад, что этим приложением можно воспользоваться. Мы обычно делаем обновления для этого приложения 1 или 2 раза в неделю, поэтому в идеале мы хотели бы, чтобы 1 неделя работоспособности (которую мы могли бы достичь на нашей Windows 10 машине)

Вся помощь приветствуется

Редактировать: добавлен код TimeMgr.Milliseconds ()

private static readonly DateTime EpochDateTime = new DateTime(1970, 1, 1);
public static long Milliseconds()
{
    return (long)(DateTime.UtcNow - EpochDateTime).TotalMilliseconds;
}
``
...