【问题标题】:How do you dispose a tracelistener properly?您如何正确配置跟踪侦听器?
【发布时间】:2016-04-09 05:26:25
【问题描述】:

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

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

【问题讨论】:

  • TextWriterTraceListenerreference source,好像清理逻辑放在CloseDispose方法中,但我不知道它们是否被调用。
  • 监听器由 TraceSource 处理。不清楚你如何跟踪,水晶球说你想在程序终止时调用 Trace.Close()。

标签: c# objectdisposedexception tracelistener


【解决方案1】:

显然 ProcessExit 事件有效。 :(

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

【讨论】:

    猜你喜欢
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 2011-04-11
    • 2015-02-25
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多