使用.net 3.0是一个很好的线程恢复和挂起的替代品
本文关键字:线程 很好 恢复 替代品 挂起 一个 net 使用 | 更新日期: 2023-09-27 17:50:35
我受限于。net 3.0: 这是外部强加的要求。
我需要处理来自泛型队列的字符串。主线程将对字符串进行Enqueue,工作线程将对字符串进行Dequeue,然后处理它们。在工作线程的顶部,它将自己挂起,并在有东西进入队列时等待恢复。然后清空队列(在每个项目退出队列时处理它们),然后在队列为空时挂起自己。
我创建了一个小示例程序,简洁地说明了基本逻辑。我知道enqueuedequeue需要被保护,但它们在这里是原始的,因为这不是我查询的重点。
我看了看使用信号量和互斥对象,但我理解文档的方式,似乎没有一种方法可以在不等待的情况下发出事件信号。我想要的是恢复来解除阻塞工作线程(如果它被阻塞),以便它可以通过队列循环。这个信号只在主线程向队列中添加一个项目时才会发生。如果工作线程已经在工作,那么它将继续工作,直到队列为空。需要这个信号只是为了启动工作线程,如果它被赶上了,正在等待一些事情要做。
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
}
}
}
}
}