private void SendLogEntry(WebSocketWrapper ws, LogEntry logEntry)
        {
            try
            {
                if (!ws.WebSocket.IsConnected)
                    return;

                if (ws.Expression != null && !ws.Expression.IsMatch(logEntry.Line))
                    return;

                using (var wsmsg = ws.WebSocket.CreateMessageWriter(WebSocketMessageType.Text))
                using (var writer = new StreamWriter(wsmsg, Encoding.UTF8, 1024, true))
                {
                    _serializer.Serialize(writer, logEntry);
                }
            }
            catch
            {
                DisconnectWebSocket(ws.WebSocket);
            }
        }
 private void ParallelBroadcastLogEntry(LogEntry logEntry)
 {
     try
     {
         _semaphore.EnterReadLock();
         Parallel.ForEach(
             source: _connections,
             parallelOptions: new ParallelOptions()
             {
                 CancellationToken = _cancel.Token,
                 MaxDegreeOfParallelism = Environment.ProcessorCount * 2
             },
             body: ws => SendLogEntry(ws, logEntry));
     }
     finally
     {
         _semaphore.ExitReadLock();
     }
 }