void Run(object unused)
 {
     try
     {
         string hello = _reader.ReadLine();
         Assert.That(hello == "HELLO");
         int iLine = 0;
         for ( ; ;)
         {
             var line = _reader.ReadLine();
             if (line == null)
             {
                 _endFlag = LogReceiverEndStatus.MissingEndMarker;
                 break;
             }
             if (line == "GOODBYE")
             {
                 _endFlag = LogReceiverEndStatus.Normal;
                 break;
             }
             Assert.AreEqual(line, $"Line n°{iLine++}");
         }
         Assert.AreEqual(iLine, 20);
     }
     catch (Exception ex)
     {
         _endFlag = LogReceiverEndStatus.Error;
         Assert.IsNull(ex, "There should not be any error here.");
     }
 }
        void Run()
        {
            try
            {
                int streamVersion = _reader.ReadInt32();
                if (_interProcess)
                {
                    _server.DisposeLocalCopyOfClientHandle();
                }
                for (; ;)
                {
                    var e = LogEntry.Read(_reader, streamVersion, out bool badEndOfStream);
                    if (e == null || badEndOfStream)
                    {
                        _endFlag = badEndOfStream ? LogReceiverEndStatus.MissingEndMarker : LogReceiverEndStatus.Normal;
                        break;
                    }
                    switch (e.LogType)
                    {
                    case LogEntryType.Line:
                    {
                        if (_monitor.ShouldLogLine(e.LogLevel, e.Tags, out var finalTags))
                        {
                            var d = new ActivityMonitorLogData(e.LogLevel | LogLevel.IsFiltered, finalTags, e.Text, CKException.CreateFrom(e.Exception), e.FileName, e.LineNumber);
                            d.SetExplicitLogTime(e.LogTime);
                            _monitor.UnfilteredLog(ref d);
                        }
                        break;
                    }

                    case LogEntryType.OpenGroup:
                    {
                        ActivityMonitorLogData d;
                        if (_monitor.ShouldLogLine(e.LogLevel, e.Tags, out var finalTags))
                        {
                            d = new ActivityMonitorLogData(e.LogLevel | LogLevel.IsFiltered, finalTags, e.Text, CKException.CreateFrom(e.Exception), e.FileName, e.LineNumber);
                            d.SetExplicitLogTime(e.LogTime);
                        }
                        else
                        {
                            d = default;
                        }
                        _monitor.UnfilteredOpenGroup(ref d);
                    }

                    break;

                    case LogEntryType.CloseGroup:
                        _monitor.CloseGroup(e.Conclusions, e.LogTime);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                _endFlag = LogReceiverEndStatus.Error;
                _monitor.UnfilteredLog(LogLevel.Fatal, null, "While receiving pipe logs.", ex);
            }
        }
 /// <summary>
 /// Waits for the termination of the other side.
 /// If it is known that the client has failed (typically because external process ended with a non zero
 /// return code), <paramref name="otherFailed"/> should be true: this receiver will only wait for 500 ms
 /// before returning, avoiding to wait for the internal thread termination.
 /// When <paramref name="otherFailed"/> is false, this method blocks until the client sends its goodbye
 /// message or the pipe is broken.
 /// </summary>
 /// <param name="otherFailed">True when you already know that the sender has failed.</param>
 /// <returns>The final status.</returns>
 public LogReceiverEndStatus WaitEnd(bool otherFailed)
 {
     if (otherFailed)
     {
         if (!_thread.Join(500))
         {
             _endFlag = LogReceiverEndStatus.Error;
         }
     }
     else
     {
         _thread.Join();
     }
     return(_endFlag);
 }