2

我有一个日志记录类,它包含一个线程安全队列、一个Thread为该队列提供服务的队列、一些支持信号和一个bool

private ConcurrentQueue<LogEntry> _logQ;
private Thread _thread;
private volatile bool _running;
private AutoResetEvent _logEntryWaitingSignal;
private ManualResetEvent _shutdownSignal;

构造函数体:

{
    _logEntryWaitingSignal = new AutoResetEvent(false);
    _shutdownSignal = new ManualResetEvent(false);
    _logQ = new ConcurrentQueue<XrayLogEntry>();
    _thread = new Thread(LoggingThread);
    _thread.IsBackground = false;
    _thread.Start();
}

我的线程体:

private void LoggingThread()
{
    _running = true;
    LogStore theLog = ...

    // don't exit until all queued entries are written
    while (_running || !_logQ.IsEmpty)
    {
        LogEntry entry;
        int entryCount = 0;
        while (_logQ.TryDequeue(out entry))
        {
            theLog.WriteEntry(entry);
        }
        _logEntryWaitingSignal.WaitOne();
    }
    _shutdownSignal.Set();
}

我有这段关闭代码将_running布尔值设置为false(队列不能再添加到一次_runningfalse),然后通知线程唤醒,然后等待它的信号,它已经处理了所有等待的条目并退出:

_running = false;
try
{
    _logEntryWaitingSignal.Set(); // Wakes the thread
    // Wait for thread to complete
    if(!_shutdownSignal.WaitOne(THREAD_SHUTDOWN_TIMEOUT_MILLISECONDS))
        throw new Exception("Timed out waiting for thread to exit.");
}
catch(Exception ex)
{
    ...
}

我的问题是:我能否确保调用此代码,以便在任何可能的(有序)进程终止下执行?

我已经尝试从 执行它Dispose,并实现终结器来调用Dispose. 只要Dispose被调用,例如,从FormClosed我的应用程序对话框的事件中调用,它就可以正常工作。但是,我不相信终结器可以保证按我想要的方式工作,因为似乎即使拥有记录器对象的线程退出,线程在_logEntryWaitingSignal.WaitOne()调用时仍将保持活动状态,并且进程永远不会退出。

当然,如果我把它设为后台线程,进程就会退出,但如果我这样做了,我怎样才能确保线程不会在写条目的过程中被关闭呢?

4

0 回答 0