1

c#2.0 で GDI 変換を処理するプリンター キューを実装しています。処理するジョブは、これらのジョブを処理するためにプリンタごとにスレッドを設定するメイン スレッドによって追加されます。すべてのジョブが終了すると、印刷スレッドは期限切れになる前に次のジョブを 5 秒間待機します。

次に印刷ジョブが渡されたときに、新しいスレッドが作成されます。ジョブを連続した順序で保持するには、プリンタごとにスレッドを 1 つだけにすることが重要です。

残念ながら、スレッドの有効期限が切れた直後に印刷ジョブが追加されると、競合状態が発生するようです。Thread.IsAlive は、ジョブの処理が終了した直後に true になる可能性があります。

これを防ぐことはできますか?

簡易版:

private Thread _processor;
readonly private AutoResetEvent _newPrintItemAdded = new AutoResetEvent(true);
readonly ThreadSafeQueueWrapper<IPrintItem> _printingQueue = new ThreadSafeQueueWrapper<IPrintItem>(5);

public void Add(IPrintItem item)
{
    _printingQueue.Enqueue(item);

    //Resume processing thread if waiting.
   _newPrintItemAdded.Set();

   StartProcessorIfNeeded();
 }


public void StartProcessorIfNeeded()
{
    if (_processor != null && _processor.IsAlive) return;

    _processor = new Thread(RunThread)

    _processor.Start();
}

public void RunThread()
{
    //timeout if no items added to queue
    while (_newPrintItemAdded.WaitOne(5000))
    {
        ProcessQueueItems();
    }
      //Thread is alive here, but won't process any more items
}
private void ProcessQueueItems()
{
   // get the print job off the queue
   IPrintItem currentPrinter;
   while (_printingQueue.TryDequeue(out currentPrinter))
   {
      currentPrinter.Print();
   }
}
4

1 に答える 1

2

古いスレッドが終了するのを待ちます。プーリング ソリューションIsAliveはほとんど機能しないため、使用しないでください。

if (_processor != null) _processor.Join();
于 2013-02-27T12:24:11.983 に答える