【发布时间】:2016-11-16 12:47:27
【问题描述】:
我正在处理一个项目,该项目需要阻塞一个正在运行的线程一段时间,时间跨度可能在一秒到几个月之间变化。
我想出的方法是使用 EventWaitHandle.WaitOne 方法(或其任何同级方法)并指定超时。问题是所有这些方法都将 Int32 作为参数,将最大阻塞时间限制为大约 25 天。
有人知道解决办法吗?如何将线程阻塞更长的 Int32.MaxValue 毫秒?
谢谢
更新
只是为了记录,这是我最终想出的代码sn-p:
while(_doRun)
{
// Determine the next trigger time
var nextOccurence = DetermineNextOccurence();
var sleepSpan = nextOccurence - DateTime.Now;
// if the next occurence is more than Int32.MaxValue millisecs away,
// loop to work around the limitations of EventWaitHandle.WaitOne()
if (sleepSpan.TotalMilliseconds > Int32.MaxValue)
{
var idleTime = GetReasonableIdleWaitTimeSpan();
var iterationCount = Math.Truncate(sleepSpan.TotalMilliseconds / idleTime.TotalMilliseconds);
for (var i = 0; i < iterationCount; i++)
{
// Wait for the idle timespan (or until a Set() is called).
if(_ewh.WaitOne(idleTime)) { break; }
}
}
else
{
// if the next occurence is in the past, trigger right away
if (sleepSpan.TotalMilliseconds < 0) { sleepSpan = TimeSpan.FromMilliseconds(25); }
// Wait for the sleep span (or until a Set() is called).
if (!_ewh.WaitOne(sleepSpan))
{
// raise the trigger event
RaiseTriggerEvent();
}
}
}
那个 sn-p 是由专用线程执行的代码。请注意,EventWaitHandle.Set() 仅在应用程序退出或希望取消调度程序时调用。
感谢那些愿意提供帮助的人。
【问题讨论】:
-
您真的认为您的应用程序可以运行那么长时间吗?在测试期间它肯定会在第 23 天崩溃
-
在我看来,设计存在严重问题。
-
你应该在某个事件上开始你的线程。或者使用不会浪费的定时器来接线程。
-
线程是工作线程,它们的工作单元以 CPU 周期来衡量。你不会雇佣一个工人然后付钱让他们休眠一万亿秒,所以不要雇佣一个线程并付钱让它休眠一万亿个 CPU 周期。线程不是为长时间运行的事务而设计的;使用不同的机制。
-
@JuiceOntour 是的,但我很有信心地说,任何需要线程可能因 int.MaxValue 或更多而被阻塞的情况都可以重新设计为不需要。
标签: c# multithreading c#-4.0 thread-synchronization