通过事件调度时,对象接收为null

时间:2018-09-14 22:36:23

标签: c# multithreading events null garbage-collection

我有一个相当基本的Logger

public class Logger: ILogger
{
  public event EventHandler<MessageLoggedArgs> MessageLogged;
  ...
  public void LogMessage(string msg, LogType logType)
  {
    var logItem = new LogItem(msg, logType);
    addLogMessage(logItem);
  }

  private void addLogMessage(LogItem logItem)
  {
    MessageLogged?.Invoke(this, new MessageLoggedArgs(logItem));
  }
}

public class MessageLoggedArgs
{ 
   public LogItem LogItem {get;}
   public MessageLoggedArgs(LogItem logitem)
   {
       LogItem = logItem;
   }
}

public class LogsProcessor
{ 
    public LogsProcessor(ILogger logger)
    {
        _logger = logger;
        _logger.MessageLogged += OnMessageLogged;

    }

    private volatile List<LogItem> buffer = new List<LogItem>();

    private ManualResetEvent ev = new ManualResetEvent(true);

    private void OnMessageLogged(object sender, MessageLoggerArgs e)
    {
        buffer.Add(e.LogItem);
        ev.Set();
    }

    //Runs on a thread
    private void process()
    {
       while(true)
       {
          ev.WaitOne(Timeout.Infinite);

          if(buffer.Count != 0)
          {
              while(buffer.Count != 0)
              {
                  var item = logbuffer[0];
                  buffer.RemoveAt(0);
                  Application.Current.Dispatcher.BeginInvoke
                                 ( new Action( () => { //Log to UI }));
              }

          }
          else
             ev.Reset();
       }
    }
}

此类的使用者在生成大量日志时会收到一些空对象。这些对象是否有可能被垃圾回收了?如果是,那么即使在MessageLoggedAgs内部始终存在对活动对象的引用,也有可能对日志进行垃圾回收。 这让我感到困惑。

编辑:事实证明,问题出在某种程度上是由于使用线程访问了缓冲区。我可以通过使用ConcurrentQueue消除此问题。但是,我不知道问题在何处。我以为如果我使用单个线程访问缓冲区,那将不是问题。

0 个答案:

没有答案