2016-01-05 10 views
1

Я на самом деле написал компонент tracelistener, который регистрируется в сетевом потоке. Код для этого здесь:Как вы правильно распоряжаетесь tracelistener?

using Newtonsoft.Json.Linq; 
using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading.Tasks; 

namespace System.Diagnostics 
{ 
    public class NetworkStreamWriterTraceListener : DelimitedListTraceListener 
    { 
     NetworkStream _stream; 
     StreamWriter _writer; 
     StreamReader _reader; 
     TcpClient client; 
     bool IsDisposed = false; 
     private NetworkStream GetStream(string configJson) 
     { 
      JObject config = JObject.Parse(configJson); 
      if (config["port"] == null) 
      { 
       throw new Configuration.ConfigurationErrorsException("port missing from json configuration"); 
      } 
      client = new TcpClient(); 
      int port = config["port"].Value<int>(); 
      client.Connect("localhost", port); 
      return client.GetStream(); 
     } 

     public NetworkStreamWriterTraceListener(string configJson): base(TextWriter.Null) 
     { 
      Initialize(configJson);    
     } 

     public NetworkStreamWriterTraceListener(string configJson, string name) : base(TextWriter.Null, name) 
     { 
      Initialize(configJson); 
     } 

     private void Initialize(string configJson) 
     { 
      _stream = GetStream(configJson); 
      _writer = new StreamWriter(_stream); 
      _reader = new StreamReader(_stream); 
      Writer = _writer;    
      _reader.ReadLine(); 
      //TODO: parse response code 

      SendCommand("IDTY", configJson); 

      _reader.ReadLine(); 
      //TODO: parse response code 

      AppDomain.CurrentDomain.ProcessExit += (s, e) => 
      { 
       SendCommand("QUIT", "closing connection"); 
      }; 
      AppDomain.CurrentDomain.DomainUnload += (s, e) => 
      { 
       SendCommand("QUIT", "closing connection"); 
      }; 
     } 

     public void SendCommand(string Command, string Data) 
     { 
      this.Writer.WriteLine("{0} {1}", Command, Data); 
      this.Writer.Flush(); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      base.Dispose(disposing); 
      IsDisposed = true; 
     } 

     public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) 
     { 
      Write("LMSG "); 
      base.TraceEvent(eventCache, source, eventType, id, message); 
      Flush(); 
     } 

     public override void Close() 
     {    
      base.Close(); 
     } 
    } 
} 

Теперь я импортировал и использовал этот компонент tracelistener, успешно добавив его через конфигурацию.

Существует проблема с тем, как этот компонент предназначен для использования. До своего «расположенного» (т. Е. В общем смысле, а не в смысле сети .net) его предполагается отправить сообщение вниз по течению, сигнализирующее о завершении процесса нисходящего потока, чтобы нисходящий процесс мог освободить связанное соединение сокета.

Я попытался переопределить метод Dispose, но кажется, что метод никогда не будет вызван каркасом. Пытался написать подпрограмму деструкторов, но всякий раз, когда я пытаюсь очистить поток записи, он сгенерирует ObjectDisposedException

~NetworkStreamWriterTraceListener() 
{ 
    if(client.Connected) 
    { 
     Send("QUIT", "done with operation"); 
     client.Close(); 
    } 
} 

Я также попытался закреплять в AppDomain событий. Они тоже не работали.

+1

Глядя на 'TextWriterTraceListener' [ссылка источника] (http://referencesource.microsoft.com/#System/compmod/system/diagnostics/TextWriterTraceListener.cs,7fdde189840b2aa2), выглядит как логика очистки является размещенных в методах 'Закрыть' и' Dispose', но я понятия не имею, вызваны они или нет. –

+1

Слушатели размещены * TraceSource *. Не ясно, как вы трассируете, хрустальный шар говорит, что вы хотите позвонить Trace.Close() при завершении программы. –

ответ

1

Видимо, событие ProcessExit работает. :(

 AppDomain.CurrentDomain.ProcessExit += (s, e) => 
     { 
      SendCommand("QUIT", "closing connection"); 
      _reader.ReadLine(); 
      //TODO : verify the response code received 
      client.Close(); 
     }; 

 Смежные вопросы

  • Нет связанных вопросов^_^