C# 多线程:微线程休眠的开销

Set*_*ron 0 c# multithreading

我有一个应用程序可以抓取另一个桌面的快照。该进程被放置在单独的后台工作线程中并异步运行。DoWork 事件的小模型是:

private void GrabImage_DoWork(object sender, DoWorkEventArgs e)
{
 /*Grab the image..*/
 System.Threading.Thread.Sleep(10)
}
Run Code Online (Sandbox Code Playgroud)

目前放置了一个 thread.sleep(10) ,我只是想知道这么小的睡眠是否真的会由于不断的额外的不需要的上下文切换而导致性能变差。

如果问题需要进一步解释,请告诉我。干杯,

编辑:决定添加更多上下文以帮助专注于特定答案。

提出的问题 问:这是当前正在运行的唯一后台线程吗?答:不。实际上有一些后台工作线程以及一个使用 .NET Threadpool 类对多个线程进行排队的线程。因此,睡眠最初被放入代码中是为了允许这些其他线程发生上下文切换。然而,我相信无论如何操作系统都是时间切片的,这样我确信如果没有睡眠,其他线程将有机会执行?

问:这个后台工作者是否一直在运行?答:该应用程序提供了一个与桌面交互的界面,并带有一个切换按钮来显示背景图像。因此,如果按钮被切换,后台工作人员实际上可能会关闭或不断地搅动。

我希望总体问题对于性能来说并不是不重要。我试图在性能和可用性之间找到一个良好的平衡。

Ree*_*sey 5

睡眠可能会导致额外的上下文切换,因为它将允许其他线程在您的进程中执行。

但是,听起来您有一个后台工作线程。如果是这种情况,您可能无论如何都会进行上下文切换。这种情况往往会在后台工作人员报告进度时发生(因为他们是跨线程调用)。对于其中一个,我怀疑您会注意到所涉及的性能影响,尽管唯一确定的方法是分析您的应用程序。

我更大的问题是:为什么你首先要在这里添加这个睡眠,特别是如果这是你担心的事情。通常,您会在此处专门添加睡眠以允许其他线程工作,这通常会导致上下文切换。如果您是有意这样做的,那么就不用担心。另一方面,如果您不需要此睡眠,则没有理由包含它。


编辑:以下是回复您的编辑的一些具体信息:

问:这是当前正在运行的唯一后台线程吗?答:不。实际上有一些后台工作线程以及一个使用 .NET Threadpool 类对多个线程进行排队的线程。因此,睡眠最初被放入代码中是为了允许这些其他线程发生上下文切换。然而,我相信无论如何操作系统都是时间切片的,这样我确信如果没有睡眠,其他线程将有机会执行?

操作系统将进行时间切片,但(默认情况下)该线程将具有默认优先级。理论上,它应该获得与主线程和其他线程运行一样多的处理器时间。您不必睡觉,但有时这是有利的(见下文)。

问:这个后台工作者是否一直在运行?答:该应用程序提供了一个与桌面交互的界面,并带有一个切换按钮来显示背景图像。因此,如果按钮被切换,后台工作人员实际上可能会关闭或不断地搅动。

如果工作线程将处于循环中并不断消耗 CPU,那么添加一些机制来防止它耗尽整个 CPU 核心通常是有利的(除非您需要该线程中的实时性能)。短暂的睡眠(尽管 Sleep(0) 对此也同样有效)是一个简单的选择。然而,如果算法对此有意义的话,最好将某种类型的 WaitHandle 放在适当的位置,这样您就可以只根据需要工作。这实际上取决于算法。

由于我已经在使用 Threadpool 类,因此也将此工作负载排队到线程池类上,而不是单独的后台工作者上。

BackgroundWorker 类使用 ThreadPool 线程,因此这样做并没有真正的优势。然而,BackgroundWorker 使针对 UI 线程的工作变得更加简单,因此,如果您在 UI 上显示进度,那么使用 BW 来完成此操作可能会更容易,就像您现在所做的那样。