Бегининвок выполнен с существенной задержкой - PullRequest
0 голосов
/ 20 ноября 2019

У меня есть консольное приложение, которое получает сообщения от клиентов и отправляет их на сервер через веб-сокеты.

    // there we receive the request from the client app
    private void onMessage(object sender, MessageEventArgs e)
    {
       Task.Factory.StartNew((Action) (() =>
      {
        Thread.CurrentThread.Priority = ThreadPriority.Normal;

        sendAsync(opcode, new MemoryStream(data), callback, msg);
      }), CancellationToken.None, TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness, TaskScheduler.Default).ConfigureAwait(false);
    }

    private void sendAsync(Opcode opcode, Stream stream, Action<bool> completed, string data)
    {
        _logger.Info("before invoke " + DateTime.Now);

        Func<Opcode, Stream, string, bool> sender = send;
        sender.BeginInvoke(
            opcode,
            stream, data,
            ar =>
            {
                completed(sent);
            },
            null);
    }

    private bool send(Opcode opcode, Stream stream, string msg)
    {
        _logger.Info("before lock " + DateTime.Now);
        lock (_forSend)
        {
            // write to the stream
        }
    }

Как вы можете видеть, что мы используем BeginInvoke в sendAsync. В большинстве случаев все работает нормально, но иногда перед выполнением делегата происходит значительная задержка, и мы получаем такие журналы:

 Win32 Thread Id 29796: before invoke 11/20/2019 21:40:52
 Win32 Thread Id 36976: before lock 11/20/2019 21:41:22

Почему это может произойти?

1 Ответ

0 голосов
/ 21 ноября 2019

Возможно, это не тот ответ, которого вы ожидаете, но я сталкивался с некоторыми подобными проблемами раньше. Почти во всех случаях это не пул потоков слишком занят, вместо этого всегда были ошибки разработчика.

Судя по журналу, так как время между журналами составляет 30 секунд, ясказал бы, что какой-то разработчик может установить 30-секундный таймер или блокировку с тайм-аутом на 30 секунд. Поскольку 30 секунд - это магическое число для разработчиков (у многих команд также есть тайм-аут по умолчанию на 30 секунд).

Так что, держу пари, это ошибка пользователя.

...