我有一个日志记录类,其中包含一个线程安全队列,一个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
(队列无法再添加到_running
false
),然后发出信号要唤醒的线程,然后等待它已经处理了所有等待条目的信号并退出:
_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()
调用时保持活动状态,并且永不退出。
当然,如果我将它作为后台线程,那么进程将退出,但如果我这样做,我怎样才能确保线程在写入条目的过程中不会被关闭?