在我的一个项目中,我需要安排一项任务在后台线程中的某个指定时间间隔后完成。我使用 ThreadPool.RegisterWaitForSingleObject
机制来做到这一点。
根据文档,第一个参数可能是 WaitHandle
,它有许多子类。起初我更喜欢 ManualResetEvent
;我使用这个事件来发出完成时间表和退出的信号。这是我的代码:
public class ScheduleTester
{
private long m_LastTicks;
private RegisteredWaitHandle m_RegisterWaitHandle;
public ManualResetEvent Event;
public ScheduleTester()
{
Event = new ManualResetEvent(false);
m_RegisterWaitHandle = ThreadPool.RegisterWaitForSingleObject(Event, new WaitOrTimerCallback(WaitOrTimerCallback), null, 500, false);
m_LastTicks = DateTime.Now.Ticks;
}
private void WaitOrTimerCallback(object state, bool timedOut)
{
long ticks = DateTime.Now.Ticks;
if (timedOut)
{
Console.WriteLine(string.Format("Timeout : {0} ... Do scheduled job takes 1 seconds long, Thread ID : {1}", (ticks - m_LastTicks) / 10000f, Thread.CurrentThread.GetHashCode()));
}
else
{
Console.WriteLine(string.Format("Signaled....Unregister , Thread ID : {0}", Thread.CurrentThread.GetHashCode()));
if (null != m_RegisterWaitHandle)
m_RegisterWaitHandle.Unregister(null);
}
m_LastTicks = ticks;
}
}
static void Main()
{
ScheduleTester waitFor = new ScheduleTester();
Console.ReadKey();
waitFor.Event.Set();
Console.ReadKey();
}
最佳答案
是的,这不是非常直观的行为。您可以从调试器的“调试”>“Windows”>“线程”窗口轻松查看潜在问题。您会看到大量 tp 线程都在执行您的 WaitOrTimerCallback() 方法。
阻止这种情况发生的责任在于你。 RWFSO 的executeOnlyOnce
参数非常非常重要。您现在传递了 false
,这使得您等待的同步对象只收到一次信号非常重要。就像 AutoResetEvent 一样。
如果您使用 ManualResetEvent,那么您必须传递 true。并将您的回调调整为:
private void WaitOrTimerCallback(object state, bool timedOut) {
long ticks = DateTime.Now.Ticks;
if (timedOut) {
Console.WriteLine(string.Format("Timeout : {0} ... Do scheduled job takes 1 seconds long, Thread ID : {1}", (ticks - m_LastTicks) / 10000f, Thread.CurrentThread.ManagedThreadId));
ThreadPool.RegisterWaitForSingleObject(Event, new WaitOrTimerCallback(WaitOrTimerCallback), null, 500, true);
}
else {
Console.WriteLine(string.Format("Signaled....Unregister , Thread ID : {0}", Thread.CurrentThread.ManagedThreadId));
m_RegisterWaitHandle.Unregister(null);
}
m_LastTicks = ticks;
}
您现在将看到它在等待间隔检测超时。不确定这是不是故意的。
关于c# - RegisterWaitForSingleObject 未定义行为与 ManualResetEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37482869/