我有一个 Windows 服务,它以 5 个线程之一发送电子邮件(这样做是为了提高服务发送电子邮件的速度):
private AutoResetEvent block;
private ThreadedQueue<Message> messageQueue;
private void DoSend()
{
try
{
while(!this.disposing)
{
this.block.WaitOne();
Message message = null;
if (this.messageQueue.TryDequeue(out message))
{
this.block.Set();
}
if(message != null)
{
this.Send(message);
}
}
}
catch(Exception ex)
{
// Log
}
}
我有一种Queue
方法可以将一条或多条新消息添加到 messageQueue 并调用block.Set()
,以便 5 个线程之一可以发送消息。当允许其中一个线程运行时,只要队列中有消息,block.Set()
就会调用,以便下一条消息可以出队,并且 5 个线程中的另一个将工作发送它。以此类推,直到队列为空。这一切正常。
但是,当我处理我的对象时,我设置了处理变量,然后为每个线程:
if(thread.ThreadState == ThreadState.Running)
{
thread.Join();
}
else if(thread.ThreadState == ThreadState.WaitSleepJoin)
{
thread.Abort();
}
大多数情况下,线程由于 s 而处于休眠状态block.WaitOne
,因此上面的代码中止了线程。但是,这会导致记录线程中止异常。我可以将线程中止异常与其他异常分开捕获并选择不记录,但这似乎不是很干净。
在不导致过多日志记录的情况下清理这些线程的最佳方法是什么?
更新:
我已将以上内容更改为:
private ManualResetEvent block;
private ThreadedQueue<Message> messageQueue;
private void DoSend()
{
try
{
while(!this.disposing)
{
this.block.WaitOne();
Message message = null;
if (!this.messageQueue.TryDequeue(out message) && !this.disposing)
{
// There's nothing else to send for now to block the sending threads
// unless we're disposing as we want the other threads to exit too
this.block.Reset();
}
if(message != null)
{
this.Send(message);
}
}
}
catch(Exception ex)
{
// Log
}
}
public void Dispose()
{
this.disposing = true;
this.block.Set();
foreach(Thread thread in this.sendingThreads) {
thread.Join();
}
this.block.Dispose();
this.sendingThreads = null;
}
谢谢您的帮助。