我有一个需要等待大约3-4个小时的Winform。我不能关闭并以某种方式重新打开应用程序,因为它在后台做了很少的事情,而它等待。
为了实现等待 - 不会给UI线程带来麻烦和其他原因 - 我有一个BackgroundWorker,我向其发送等待多少毫秒并在其doWork事件中调用Thread.Sleep(waitTime);
。在backGroundWorker_RunWorkerCompleted
事件中,我会在等待之后执行该程序应该执行的操作。
这在开发机器上运行良好。即等待必须结束。但是在测试机上,它一直在等待更长时间。它发生了两次,第一次等待超过规定时间1小时,第二次等待约2小时40分钟。
有没有明显的理由发生这种情况,或者我错过了什么?
开发机器是Win XP,测试机器是Win 7。
答案 0 :(得分:3)
我建议改用ManualResetEvent:
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx
ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne(waitTime);
...
//your background worker process
mre.Set();
作为奖励,您将有能力更快地中断此睡眠。
答案 1 :(得分:2)
在我看来,等待时间的差异不能仅仅通过你给我们的信息来解释。我真的认为差异的原因在于开始睡眠的那一刻。所以实际的Thread.sleep(waitTime);
电话。你确定在你认为的那一刻就调用了睡眠吗?
而且,正如评论所建议的,如果你真的需要等待这么久;考虑使用Timer
来启动所需的事件。或者甚至在您的应用程序中安排某种类型。当然,这取决于您的实际实施,因此说起来容易做起来难。但感觉很愚蠢,让BackgroundWorker睡了这么久。
答案 2 :(得分:2)
查看this article,其中解释了原因:
Thread.Sleep(n)表示阻止当前线程至少为该号码 可以在n内发生的时间片(或线程量子) 毫秒。时间片的长度因不同而不同 Windows的版本/类型和一般的不同处理器 范围从15到30毫秒。这意味着线程差不多 保证阻止超过n毫秒。可能性 你的线程将在n毫秒之后完全重新唤醒 不可能,因为不可能。所以,Thread.Sleep毫无意义 定时。
顺便说一下,它还解释了为什么不使用Thread.Sleep;)
我同意其他建议使用Timer而不是Thread.Sleep。
答案 3 :(得分:1)
PREFIX:这需要.NET 4或更高版本
考虑让你的函数异步并简单地执行:
await Task.Delay(waitTime);
或者,如果你不能使你的功能异步(或者不想),你也可以这样做:
Task.Delay(waitTime).Wait();
这是一个单行解决方案,任何拥有Reflector副本的人都可以验证Task.Delay是否在内部使用了计时器。