我正在编写一个使用单独线程进行日志记录的应用程序。 我想在主线程停止时停止单独的线程。但是我无法确定何时完全停止记录器线程,因为我不知道主线程何时停止。 C#中是否有一种机制可以在主线程停止时发送通知? (或者你能想到我的问题的另一种解决方案吗?)
// This class automatically applies on each call of every method of Main() function
public class CommandLoggingAdvice : IMethodInterceptor
{
private static ProducerConsumerClass LoggingQueue = ProducerConsumerClass.Instance;
LoggingQueue.AddTask("Logging message on call of *method*");
}
public sealed class ProducerConsumerClass
{
// here Iget an instance of log4net
private ILog _Logger = null;
protected ILog Logger
{
_Logger = LogManager.GetLogger("Logger1");
}
private BlockingCollection<string> tasks = new BlockingCollection<string>();
private static volatile ProducerConsumerClass _instance;
Thread worker;
private Thread mainthread;
private ProducerConsumerClass()
{
mainthread = Thread.CurrentThread;
worker = new Thread(Work);
worker.Name = "Queue thread";
worker.IsBackground = false;
worker.Start(mainthread);
}
public static ProducerConsumerClass Instance
{
get
{
if (_instance == null)
{
_instance = new ProducerConsumerClass();
}
}
}
public void AddTask(string task)
{
tasks.Add(task);
}
void Work(object mainthread)
{
Thread ma = (Thread) mainthread;
if(ma.ThreadState != ThreadState.Stopped)
{
tasks.CompleteAdding();
}
while (true)
{
string task = null;
if (!tasks.IsCompleted)
{
task = tasks.Take();
Logger1.Info(task);
}
else
{
return;
}
}
}
}
如果BlockingCollection为空且应用程序仍在工作,则循环调用另一个Take()和结果:logger线程现在暂停。所以当主线程.Threadstate ==停止时,我需要杀死记录器线程
有关问题的更多信息已添加到评论中
答案 0 :(得分:2)
如果BlockingCollection
为空且标记为已完成,则您已在该线程中有代码退出。您的循环检查IsCompleted
并退出。
您需要的是主线程在集合上调用CompleteAdding
的某种方式。我建议您在ProducerConsumerClass
中使用公开方法:
public void AllDone()
{
tasks.CompleteAdding();
}
因此主线程在完成处理后可以调用AllDone
。然后,您的线程将清空队列并退出。
顺便说一下,编写日志循环的更简洁方法是:
foreach (string task in tasks.GetConsumingEnumerable())
{
Logger1.Info(task);
}
这也使得将来更容易添加取消支持。