1

我实际上已经编写了一个记录到网络流的跟踪侦听器组件。代码在这里:

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 事件。他们也没有工作。

4

1 回答 1

1

显然 ProcessExit 事件有效。:(

        AppDomain.CurrentDomain.ProcessExit += (s, e) =>
        {
            SendCommand("QUIT", "closing connection");
            _reader.ReadLine();
            //TODO : verify the response code received
            client.Close();
        };
于 2016-01-05T14:58:04.810 回答