以下是某些人想在生产应用中使用的代码(不是我,诚实) - 我想要一些独立的反馈意见。
public class JobProcessor<TJob> : IJobProcessor<TJob> where TJob : class
{
private readonly IJobQueue<TJob> theJobQueue =
new NullQueue<TJob>();
private Thread processorThread;
private bool shutdownRequested;
private readonly IJobObserver<TJob> theObserver = new NullObserver<TJob>();
public AutoResetEvent threadStartedEvent = new AutoResetEvent(false);
private int processorThreadId = 0;
private volatile TJob currentJob = null;
public JobProcessor(IJobQueue<TJob> jobQueue, IJobObserver<TJob> observer)
{
if (observer != null)
{
theObserver = observer;
}
shutdownRequested = false;
theJobQueue = jobQueue;
CreateAndRunThread();
}
private void CreateAndRunThread()
{
processorThread = new Thread(Run)
{
Name = "Tpk Processor Thread", IsBackground = true
};
processorThread.SetApartmentState(ApartmentState.STA);
processorThread.Priority = ThreadPriority.BelowNormal;
processorThread.Start();
}
public void Shutdown()
{
threadStartedEvent.WaitOne();
shutdownRequested = true;
theJobQueue.Interrupt(processorThreadId);
}
public TJob CurrentJob()
{
return currentJob;
}
private void Run()
{
processorThreadId = Thread.CurrentThread.ManagedThreadId;
threadStartedEvent.Set();
while (!BufferClearedAndShutDown())
{
try
{
ProcessNextMessage();
}
catch (ThreadAbortException)
{
CreateAndRunThread();
break;
}
catch (Exception e)
{ }
}
}
private void ProcessNextMessage()
{
currentJob = theJobQueue.RetrieveJob();
if (currentJob != null)
{
theObserver.ProcessMessage(this, currentJob);
}
currentJob = null;
}
private bool BufferClearedAndShutDown()
{
return theJobQueue.IsEmpty && shutdownRequested;
}
}
}
答案 0 :(得分:2)
您是否尝试捕获ThreadAbortException然后重新创建自己?我不确定这是可能的,但无论如何,这不是一个很好的方式来玩操作系统。
如果在currentJob = theJobQueue.RetrieveJob()之后发生异常,你将失去工作;但在theObserver.ProcessMessage(this,currentJob)之前;
除非你的jobQueue是线程安全的,否则你应该在访问它时添加锁定。
答案 1 :(得分:2)
这只是一个生产者/消费者队列吗?有很多预先推出的例子 - 我几天前在这里发布了一个例子(但我现在找不到它)...这样说 - 我发布的版本是很多更简单 - 即“显然没有错误”,而不是“没有明显的错误”。我会看看能不能找到它......
(编辑:found it)
重点是;在该版本中,工作线程只是:
T item;
while(queue.TryDequeue(out item)) {
// process item
}
// queue has been closed and drained
答案 2 :(得分:1)
在不知道IJobQueue,IJobObserver或IJobProcessor的语义的情况下很难给出有用的反馈,但这里有一些突出的细节:
答案 3 :(得分:0)
代码中缺少很多上下文,但id就像在上面添加我的2便士,我同意。
在Randy的第2项中,我只使用锁定语句而不是内存屏障,这是MSDN推荐的方法,除非您在盒子上使用多个Itanium CPU(内存排序较弱)
http://msdn.microsoft.com/en-us/library/system.threading.thread.memorybarrier.aspx
我完全同意第6项。公开方法将裁判公开给职业队中的某个项目?那不是很好吗?,特别是当你讨论线程安全时,如果你需要从这个暴露给外部世界的类中获得一些信息,那就让它变成不可变的并且暴露出来。更好的封装。
答案 4 :(得分:0)
既然有些人已经回答我觉得在不偏袒任何人的情况下添加我自己的评论是安全的: - )
我不是多线程大师或任何其他所以我想发布它只是为了确保不仅仅是我认为这段代码看起来有点狡猾。