你如何妥善处理一个tracelistener?

时间:2016-01-05 11:37:46

标签: c# objectdisposedexception 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 个答案:

答案 0 :(得分:1)

显然ProcessExit事件有效。 :(

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