有很多关于使用Thread.Sleep()
方法的好坏的讨论。据我所知,它主要用于调试目的。
现在我想知道:用于我的特定目的是不是很糟糕,也就是说,不断循环它以便能够暂停/恢复线程?我这样做是因为我想暂停执行I / O操作的线程并能够以简单的方式恢复它。
I / O操作基本上只是将4096字节的块写入文件,直到所有数据都写入其中。由于文件可能很大并且需要很长时间,我希望能够暂停操作(以防它开始吃掉很多系统资源)。
我的代码,VB.NET版本:
'Class level.
Private BytesWritten As Long = 0
Private Pause As Boolean = False
'Method (thread) level.
While BytesWritten < [target file size]
...write 4096 byte buffer to file...
While Pause = True
Thread.Sleep(250)
End While
...do some more stuff...
End While
C#等价物:
//Class level.
long bytesWritten = 0;
bool pause = false;
//Method (thread) level.
while(bytesWritten < [target file size]) {
...write 4096 byte buffer to file...
while(pause == true) {
Thread.Sleep(250);
}
...do some more stuff...
}
我听说过ResetEvents,我知道他们做了什么,但我从来没有真正了解过它们。
答案 0 :(得分:3)
我认为,根据描述,我会这样做
'Class level.
Private BytesWritten As Long = 0
Private NotPaused As New Threading.ManualResetEvent(True)
变量名称的变化是合适的,因为这是它的使用方式
'Method (thread) level.
While BytesWritten < [target file size]
'...write 4096 byte buffer to file...
NotPaused.WaitOne(-1)
'...do some more stuff...
End While
要使循环暂停,请执行此操作
NotPaused.Reset()
并继续
NotPaused.Set()
答案 1 :(得分:2)
在.NET中,没有理由使用Thread.Sleep,除了在MTA线程上测试和/或调试时试图模拟冗长的操作,因为它会阻塞。
也许另一种选择是使用TPL。由于您不想阻止,因此可以使用Task.Delay。您可能知道,Task表示异步操作。
答案 2 :(得分:1)
我认为更优雅的方法是让线程无限期地睡眠,直到它被另一个调用Thread.Interrupt的线程唤醒,该线程正在休眠。在示例代码中有一个很好的示例:Pausing and Resuming Threads。
答案 3 :(得分:1)
我可能会误解你在这里尝试实现的目标,但从我看到的情况来看,似乎你在IO任务完成之前试图阻止一个线程。信号量将是这里最好的选择,而不是做Thread.Sleep()。
大多数操作系统都提供阻塞信号量,使线程永久休眠,直到另一个线程唤醒它。你可能最好不要使用它们而不是经常自己检查。
Thread.Sleep()和阻塞信号量都使线程进入休眠状态,但后者在资源被释放(信号量已被签名)之前一直执行该操作。前者需要线程不断唤醒,检查并重新入睡。后者保存了这些执行周期。