static void Main(string[] args)
{
Console.WriteLine("first time 5s");
RunOperations(TimeSpan.FromSeconds(5));
Console.WriteLine("second time 7s");
RunOperations(TimeSpan.FromSeconds(7));
Console.ReadKey();
}
static void RunOperations(TimeSpan workerOperationTimeout)
{
using (var evt = new ManualResetEvent(false))
{
using (var cts = new CancellationTokenSource())
{
Console.WriteLine("registering timeout operations...");
//当evt产生终止信号或超时 WorkerOperationWait()被执行
var worker = ThreadPool.RegisterWaitForSingleObject(
evt,
//System.Threading.WaitOrTimerCallback(object state, bool timedOut)
//evt每次超时或终止时回调此方法
(state, isTimeOut) => WorkerOperationWait(cts, isTimeOut),
null,
workerOperationTimeout,
true);
Console.WriteLine("starting long running operation...");
ThreadPool.QueueUserWorkItem(_ => WorkerOperation(cts.Token, evt));
Thread.Sleep(workerOperationTimeout.Add(TimeSpan.FromSeconds(2)));
worker.Unregister(evt);
}
}
}
static void WorkerOperation(CancellationToken token, ManualResetEvent evt)
{
for(int i = 0; i < 6; i ++)
{
if(token.IsCancellationRequested)
{
//第一次,超时返回
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
//第二次,产生信号
evt.Set();
}
static void WorkerOperationWait(CancellationTokenSource cts, bool isTimeOut)
{
if(isTimeOut)
{
cts.Cancel();
Console.WriteLine("worker operation timed out and was canceled.");
}
else
{
Console.WriteLine("worker operation succeded");
}
}
运行结果

本文通过一个Demo演示了如何在C#中利用线程池的RegisterWaitForSingleObject方法,实现异步等待信号量的释放,从而提高程序执行效率。

被折叠的 条评论
为什么被折叠?



