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

时间:2016-07-23 20:23:13

标签: c# vb.net multithreading blocking thread-sleep

有很多关于使用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 个答案:

答案 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()和阻塞信号量都使线程进入休眠状态,但后者在资源被释放(信号量已被签名)之前一直执行该操作。前者需要线程不断唤醒,检查并重新入睡。后者保存了这些执行周期。