C# 需要关于线程代码的反馈

C# 需要关于线程代码的反馈,c#,multithreading,C#,Multithreading,这里有一些代码,有人想在生产应用程序中使用(不是我,老实说)-我想得到一些独立的反馈 public class JobProcessor<TJob> : IJobProcessor<TJob> where TJob : class { private readonly IJobQueue<TJob> theJobQueue = new NullQueue<TJob>(); private Thread processorThre

这里有一些代码,有人想在生产应用程序中使用(不是我,老实说)-我想得到一些独立的反馈

 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;
  }
 }
}
公共类JobProcessor:IJobProcessor,其中TJob:class
{
私有只读IJobQueue作业队列=
新的NullQueue();
私有线程处理器读取;
私人布尔关闭请求;
private readonly IJobObserver theObserver=new NullObserver();
public AutoResetEvent threadStartedEvent=new AutoResetEvent(false);
私有int-processorThreadId=0;
private volatile TJob currentJob=null;
公共JobProcessor(IJobQueue jobQueue,IJobObserver observer)
{
如果(观察者!=null)
{
观察者=观察者;
}
关闭请求=错误;
作业队列=作业队列;
CreateAndRunThread();
}
私有void CreateAndRunThread()
{
processorThread=新线程(运行)
{
Name=“Tpk处理器线程”,IsBackground=true
};
ProcessorRead.SetApartmentState(ApartmentState.STA);
ProcessorRead.Priority=ThreadPriority.BelowNormal;
processorThread.Start();
}
公共空间关闭()
{
threadStartedEvent.WaitOne();
关机请求=真;
中断(ProcessorReadId);
}
公共TJob CurrentJob()
{
返回当前工作;
}
私家车
{
processorThreadId=Thread.CurrentThread.ManagedThreadId;
threadStartedEvent.Set();
而(!BufferClearedAndShutDown())
{
尝试
{
ProcessNextMessage();
}
捕获(线程异常)
{
CreateAndRunThread();
打破
}
捕获(例外e)
{  }
}
}
私有void ProcessNextMessage()
{
currentJob=theJobQueue.RetrieveJob();
if(currentJob!=null)
{
ProcessMessage(此,当前作业);
}
currentJob=null;
}
私有bool BufferClearedAndShutDown()
{
返回JobQueue.IsEmpty&请求关闭(&S);
}
}
}

您的线程是否试图捕获ThreadAbortException,然后重新创建自身?我不确定这是否可能,但无论如何,这不是一个好的方式来玩操作系统

如果在currentJob=theJobQueue.RetrieveJob()之后发生异常,您将丢失作业;但在observer.ProcessMessage(此,currentJob)之前


除非您的作业队列是线程安全的,否则您应该在访问它时添加锁定。

您的线程是否试图捕获ThreadAbortException,然后重新创建自己?我不确定这是否可能,但无论如何,这不是一个好的方式来玩操作系统

如果在currentJob=theJobQueue.RetrieveJob()之后发生异常,您将丢失作业;但在observer.ProcessMessage(此,currentJob)之前


除非您的jobQueue是线程安全的,否则您应该在访问它时添加锁定。

如果不了解IJobQueue、IJobObserver或IJobProcessor的语义,很难给您提供有用的反馈,但以下是一些突出的细节:

  • processorThread看起来并不是真的需要它;在CreateAndRunThread中只能/应该是本地
  • shutdownRequested应标记为volatile,在将shutdownRequested设置为true后调用Thread.MemoryBarrier(),或使用Thread.VolatileWrite设置shutdownRequested字段
  • 为什么要等到线程启动后再要求它关闭呢
  • 不知道为什么需要threadStartedEvent,它的用途是什么?尤其是公开有点可怕
  • 不知道IJobQueue.Interrupt是如何实现的,很难说是否存在问题
  • 谁使用CurrentJob,为什么?感觉有风险
  • 虽然捕获您自己的ThreadAbortException将捕获大多数情况,但它不会捕获所有情况。您可以使用一个单独的监视器线程,该线程调用thread.Join,并在仔细检查BufferClearedAndShutdown()后调用CreateAndRunThread()

  • 如果不了解IJobQueue、IJobObserver或IJobProcessor的语义,很难给您提供有用的反馈,但以下是一些突出的细节:

  • processorThread看起来并不是真的需要它;在CreateAndRunThread中只能/应该是本地
  • shutdownRequested应标记为volatile,在将shutdownRequested设置为true后调用Thread.MemoryBarrier(),或使用Thread.VolatileWrite设置shutdownRequested字段
  • 为什么要等到线程启动后再要求它关闭呢
  • 不知道为什么需要threadStartedEvent,它的用途是什么?尤其是公开有点可怕
  • 不知道IJobQueue.Interrupt是如何实现的,很难说是否存在问题
  • 谁使用CurrentJob,为什么?感觉有风险
  • 虽然捕获您自己的ThreadAbortException将捕获大多数情况,但它不会捕获所有情况。您可以使用一个单独的监视器线程,该线程调用thread.Join,并在仔细检查BufferClearedAndShutdown()后调用CreateAndRunThread()

  • 这只是生产者/消费者队列吗?这里有很多预先发布的示例-我几天前在这里发布了一个示例(但我现在找不到)。。。这样说吧——我发布的版本要简单得多——即“显然没有bug”而不是“没有明显bug”。我看看能不能找到它

    (编辑:)

    重点是,;对于该版本,工作线程只执行以下操作:

    T item;
    while(queue.TryDequeue(out item)) {
        // process item
    }
    // queue has been closed and drained
    

    这只是生产者/消费者队列吗?这里有很多预先发布的示例-我几天前在这里发布了一个示例(但我现在找不到)。。。这样说吧——我发布的版本要简单得多——即“显然没有bug”而不是“没有明显bug”。我看看能不能找到它

    (编辑:)

    重点是,;对于该版本,工作线程只执行以下操作:

    T item;
    while(queue.TryDequeue(out item)) {
        // process item
    }
    // queue has been closed and drained
    

    代码中缺少很多上下文,但我只想在上面加上我的两个便士,我同意

    在Randy的第2项中,我只使用一个锁语句,而不是内存屏障,这是MSDN推荐的方法,除非