2016-01-05 53 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),貌似清理邏輯是放置在'Close'和'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(); 
     };