使用 .NET 3.0 什么是线程恢复和挂起的良好替代品

Using .NET 3.0 What is a good replacemet for thread resume and suspend

我仅限于 .NET 3.0:这是外部强加的要求。

我需要处理来自 Generic.Queue 的字符串。主线程将 Enqueue 字符串,工作线程将 Dequeue 字符串然后处理它们。在工作线程的顶部,它暂停自己并等待在有东西进入队列时恢复。然后它清空队列(在每个项目出队时处理它们),然后在队列为空时暂停自身。

我创建了一个小示例程序,它简洁地说明了基本逻辑。我知道 enqueue dequeue 需要保护,但它们在这里是原始的,因为这不是我询问的重点。

我查看了使用信号量和互斥对象,但根据我对文档的理解,似乎没有一种方法可以在不等待事件的情况下发出事件信号。我想要的是恢复以解除对工作线程的阻塞(如果它被阻塞),以便它可以循环遍历队列。仅当主线程将项目添加到队列时才会发生此信号。如果工作人员已经在工作,那么它会继续工作,直到队列为空。信号的需要只是在被赶上并等待做某事时启动工作人员。

using System;
using System.Collections.Generic;
using System.Threading;

namespace QueueProcessor
{
    class Program
    {
        static Queue<string> _Messages = new Queue<string>();
        static bool _Continue = true;
        static Thread _DequeueThread = null;

        static void Main( string[] args )
        {
            _DequeueThread = new Thread( DequeueThread );
            _DequeueThread.Start();
            for(;;)
            {
                Console.WriteLine( "Entersomething here:");
                string something = Console.ReadLine();
                if( something.Equals("quit") )
                {
                    _Continue = false;
                    ResumeThread();
                    break;
                }
                _Messages.Enqueue( something );
                ResumeThread();
            }
        }

        static void ResumeThread( )
        {
            try
            {
                _DequeueThread.Resume();  // .NET 3.0 is the limit
            }
            // If it is already resumed, the frame work throws an exception.
            // This seem unneccesary since if it is already resumed then what's the bother?
            catch( ThreadStateException ) 
            {
                Console.WriteLine( "Thread already running....." );
            }
        }

        static void SuspendThread()
        {
            _DequeueThread.Suspend(); // .NET 3.0 is the limit
        }

        static void DequeueThread()
        {
            Random randomTime = new Random();
            while( _Continue )
            {
                SuspendThread();
                while( _Messages.Count > 0)
                {
                    string message = _Messages.Dequeue();
                    Console.WriteLine( String.Format ( "Dequeue:{0}", message ) );
                    int timeout = randomTime.Next();
                    timeout %= 4000;
                    Thread.Sleep(timeout); // simulated taking a while to process message
                }
            }
        }
    }
}

这是完整的答案。谢谢 Alexi 为我指明了正确的方向。

using System;
using System.Collections.Generic;
using System.Threading;

namespace QueueProcessor
{

    class Program
    {
        static Queue<string> _Messages = new Queue<string>();
        static bool _Continue = true;
        static Thread _DequeueThread = null;
        static AutoResetEvent _Latch = null;

        static void Main( string[] args )
        {
            _DequeueThread = new Thread( DequeueThread );
            _Latch = new AutoResetEvent(false);
            _DequeueThread.Start();
            for(;;)
            {
                Console.WriteLine( "Entersomething here:");
                string something = Console.ReadLine();
                if( something.Equals("quit") )
                {
                    _Continue = false;
                    ResumeThread();
                    break;
                }
                lock( _Messages )
                {
                    _Messages.Enqueue( something );
                }
                ResumeThread();
            }
        }

        static void ResumeThread( )
        {
            _Latch.Set();
        }

        static void SuspendThread()
        {
            _Latch.WaitOne();
        }

        static void DequeueThread()
        {
            Random randomTime = new Random();
            while( _Continue )
            {
                SuspendThread();
                string message = string.Empty;
                for(;;)
                {
                    lock ( _Messages )
                    {
                        message = _Messages.Count == 0 ? string.Empty : _Messages.Dequeue();
                    }

                    if( String.IsNullOrEmpty( message ) ) break; // Loop exit condition

                    Console.WriteLine( String.Format ( "Dequeue:{0}", message ) );
                    int timeout = randomTime.Next();
                    timeout %= 4000;
                    Thread.Sleep(timeout); // simulated taking a while to process message
                }
            }
        }
    }
}