Home Articles

在用于暂停线程时,循环Thread.Sleep()会不会对性能造成影响?

Asked
Viewed 1879 times
5

有(或者已经有)很多关于使用 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,我对他们的所作所为有所了解,但我从未真正了解过它们 .

4 Answers

  • 3

    在.NET中,没有理由使用Thread.Sleep,除了在MTA线程上测试和/或调试时试图模拟冗长的操作,因为它会阻塞 .

    也许另一种选择是使用TPL . 由于您不想阻止,您可以使用Task.Delay . 您可能知道,Task表示异步操作 .

  • 2

    我可能误解了你在这里想要实现的目标,但从我看到的情况来看,似乎你试图在IO任务完成之前阻塞一个线程 . 信号量将是这里最好的选择,而不是做Thread.Sleep() .

    大多数操作系统都提供阻塞信号量,使线程永久休眠,直到另一个线程唤醒它 . 你可能最好不要使用它们而不是经常自己检查 .

    Thread.Sleep()和阻塞信号量都使线程进入休眠状态,但后者在资源被释放(信号量已被签名)之前一直执行它 . 前者需要线程不断唤醒,检查并重新入睡 . 后者保存了这些执行周期 .

  • 1

    我想,根据描述,我会这样做

    '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

    我认为更优雅的方法是让线程无限期地睡眠,直到它睡着了.1840824_s . 在示例代码中有一个很好的示例:Pausing and Resuming Threads .

Related