使用 .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
}
}
}
}
}
我仅限于 .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
}
}
}
}
}