.NET 后台工作者对象的线程优先级
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/524483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.NET Backgroundworker Object's Thread Priority
提问by Soundar Rajan
I am trying to use the .NET Backgroundworker Object in an application I am developing.
我正在尝试在我正在开发的应用程序中使用 .NET Backgroundworker 对象。
All the material on the internet say that this object runs in the "background" but nowhere have I been able to confirm that this background thread indeed runs in a "low priority" mode. This question arises because in Windows (I assume) a background task can run in a 'normal' or 'below normal' or 'low' priority mode.
互联网上的所有材料都说这个对象在“后台”运行,但我无法确认这个后台线程确实以“低优先级”模式运行。出现这个问题是因为在 Windows 中(我假设)后台任务可以在“正常”或“低于正常”或“低”优先级模式下运行。
In my application, I tried to set the priority myself inside the DoWork function by calling ...
在我的应用程序中,我尝试通过调用 ...
Thread.CurrentThread.Priority=ThreadPriority.Lowest
...
...
but this seems to have no effect. Does the backgroundworker ignore this call?
但这似乎没有效果。后台工作人员是否会忽略此调用?
I would like to explain some more:
我想再解释一下:
My application is an internet client that collects real-time data on temperature,humidity etc from a chamber and uploads to a web page (not a web service) using
我的应用程序是一个互联网客户端,它从房间收集温度、湿度等的实时数据,并使用上传到网页(不是网络服务)
system.net.webclient.UploadValuesAsync(...)calls
system.net.webclient.UploadValuesAsync(...)电话
I have written the application such that the client GUI collects the data from the chamber, time-stamps them and then queues them for upload like so
我已经编写了应用程序,以便客户端 GUI 从房间收集数据,给它们打上时间戳,然后像这样将它们排队上传
...
...
Synclock objlock
debug.print("Queueing reading...")
dataQ.Enque(reading)
End Synclock
...
The backgroundworker's Dowork function dequeues and then uploads like so...
backgroundworker 的 Dowork 函数出列,然后像这样上传......
..............
………………
Do
if dataQ.count() <> 0 then
Synclock objlock
reading = dataQ.DeQue()
End Synclock
Dim client As New System.Net.WebClient
...put the reading in NameValueCollection and upload to server page
req = new NameValueCollection
...
...
client.UploadValuesAsync(uri, "POST", req)
endif
thread.sleep(1) 'without this line the CPU usage goes upto 100% and seems to slow other tasks!
Loop
................
…………………………………………………………………………………………………………………………………………
When I run the program I find that whenever the UploadValuesAsync is called the print out the debug window stops. I had also added debug statements to see how many readings are in the queue at any time. It this task is truly run in a low priority, I expected to see the queue count increase rapidly as data is acquired and then decrease only when foreground is idle and data is not being acquired. But this is not the case. As soon as a reading is added to the queue it is dequeued and uploaded. So the queue count is always is either 1 or 0!
当我运行程序时,我发现每当调用 UploadValuesAsync 时,调试窗口就会停止。我还添加了调试语句以随时查看队列中有多少读数。如果此任务确实以低优先级运行,我希望看到队列计数随着获取数据而迅速增加,然后仅在前台空闲且未获取数据时减少。但这种情况并非如此。一旦将读数添加到队列中,它就会出列并上传。所以队列计数始终是 1 或 0!
Is there something wrong in my approach? Should I not be using the background-worker object at all?
我的方法有问题吗?我应该根本不使用后台工作对象吗?
BTW, this is in a dual-core laptop running Windows XP.
顺便说一句,这是在运行 Windows XP 的双核笔记本电脑中。
回答by Brian Rasmussen
Just to add to what Jon and Marc have already said:
补充一下 Jon 和 Marc 已经说过的内容:
Background threads do not have lower priority. The difference between foreground and background threads is that the CLR will shutdown the process once no more foreground threads are running. Thread pool threads are background threads.
后台线程没有较低的优先级。前台线程和后台线程之间的区别在于,一旦没有更多的前台线程在运行,CLR 将关闭进程。线程池线程是后台线程。
You can actually set the priority of a thread pool thread, but as you have next to no control of which thread pool thread will actually run your task it is not advisable to do so. If you need threads of a specific priority you should create them using the Thread type and set the priority on the instance as desired.
您实际上可以设置线程池线程的优先级,但是由于您几乎无法控制哪个线程池线程将实际运行您的任务,因此不建议这样做。如果您需要特定优先级的线程,您应该使用 Thread 类型创建它们并根据需要在实例上设置优先级。
回答by Jon Skeet
Yes, something is wrong with your approach - you're basically tight looping when the queue is empty. Whatever the thread priorities, that's a bad idea.
是的,你的方法有问题 - 当队列为空时,你基本上是紧密循环的。无论线程优先级如何,这都是一个坏主意。
There's nothing wrong with using a background worker for this, but the enqueuing/dequeuing should really just use a producer/consumer queue which blocks when you try to dequeue when there's nothing ready.
为此使用后台工作程序没有任何问题,但是入队/出队实际上应该只使用生产者/消费者队列,当您在没有任何准备就绪的情况下尝试出队时,该队列会阻塞。
I have an example implementation of a producer/consumer queue in my threading tutorial- see about half way down the linked page. You'll want some way to tell the dequeuing process that it's finished, by the way. (For example, enqueuing a null reference or other special value.) That code was written pre-generics, but it should be easy to update.
我在我的线程教程中有一个生产者/消费者队列的示例实现- 请参阅链接页面的一半。顺便说一下,您需要某种方式来告诉出列过程它已完成。(例如,将空引用或其他特殊值排入队列。)该代码是在泛型之前编写的,但应该很容易更新。
回答by Marc Gravell
It doesn't claim to be low priority - background means a: not the UI thread, and b: it won't keep a process alive. In reality, it probably relates to ThreadPoolthreads.
它并不声称是低优先级 - 背景意味着 a:不是 UI 线程,b:它不会使进程保持活动状态。实际上,它可能与ThreadPool线程有关。
If you want a specific priority thread, then use your own Threadobject - but I wouldn't recommend even this normally...
如果你想要一个特定的优先级线程,那么使用你自己的Thread对象 - 但我通常不推荐这样做......
Additionally - "background" doesn't mean "when idle". Even on a single core machine, you will probably see both threads get as much rnutime (if they want it). Even more so on multi-core.
此外 - “背景”并不意味着“空闲时”。即使在单核机器上,您也可能会看到两个线程获得同样多的 rnutime(如果他们想要的话)。在多核上更是如此。
回答by jake.stateresa
You might want to look at this worker thread implementation. It has protected constructors for specifying the name of the thread, the priority of the thread and whether or not the thread is a background thread.
您可能想查看此工作线程实现。它具有用于指定线程名称、线程优先级以及线程是否为后台线程的受保护构造函数。

