我有一个日志记录类,它包含一个线程安全队列、一个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()
调用时仍将保持活动状态,并且进程永远不会退出。
当然,如果我把它设为后台线程,进程就会退出,但如果我这样做了,我怎样才能确保线程不会在写条目的过程中被关闭呢?