我正在尝试在我正在开发的应用程序中使用.NET Backgroundworker对象。
互联网上的所有资料都说这个对象在“背景”中运行,但我无法确认这个后台线程确实以“低优先级”模式运行。出现这个问题是因为在Windows中(我假设)后台任务可以在“正常”或“低于正常”或“低”优先模式下运行。
在我的应用程序中,我尝试通过调用在DoWork函数内设置优先级 ...
Thread.CurrentThread.Priority=ThreadPriority.Lowest
...
但这似乎没有效果。后台工作者是否忽略此调用?
我想解释一下:
我的应用程序是一个互联网客户端,它从一个房间收集有关温度,湿度等的实时数据,并使用
上传到网页(而不是网络服务) system.net.webclient.UploadValuesAsync(...)
来电
我编写了应用程序,以便客户端GUI收集来自分庭的数据,给它们加上时间戳,然后将它们排队等待上传
...
Synclock objlock
debug.print("Queueing reading...")
dataQ.Enque(reading)
End Synclock
...
背景工作者的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
................
当我运行程序时,我发现无论何时调用UploadValuesAsync,打印出来的调试窗口都会停止。我还添加了调试语句,以便随时查看队列中有多少读数。这项任务真正以低优先级运行,我希望看到队列数量在获取数据时迅速增加,然后仅在前台空闲且数据未被获取时减少。但这种情况并非如此。只要将读数添加到队列中,它就会出列并上传。所以队列数总是1或0!
我的做法有问题吗?我根本不应该使用background-worker对象吗?
BTW,这是一台运行Windows XP的双核笔记本电脑。答案 0 :(得分:14)
只是添加Jon和Marc已经说过的话:
后台线程没有较低的优先级。前台线程和后台线程之间的区别在于,一旦不再运行前台线程,CLR将关闭进程。线程池线程是后台线程。
您实际上可以设置线程池线程的优先级,但是由于您无法控制哪个线程池线程实际运行您的任务,因此不建议这样做。如果需要特定优先级的线程,则应使用Thread类型创建它们,并根据需要在实例上设置优先级。
答案 1 :(得分:7)
是的,您的方法有问题 - 当队列为空时,您基本上是紧密循环。无论线程优先级是什么,这都是一个坏主意。
使用后台工作程序没有任何问题,但是入队/出队应该只使用生产者/消费者队列,当你没有准备就绪时,当你试图出队时会阻塞它。
我有一个生产者/消费者队列in my threading tutorial的示例实现 - 看看链接页面的一半。顺便说一下,你会想要一些方法告诉出列的过程它已经完成了。 (例如,将空引用或其他特殊值排入队列。)该代码是在泛型之前编写的,但它应该很容易更新。
答案 2 :(得分:3)
它并不声称是低优先级 - 后台意味着:不是UI线程,而b:它不会使进程保持活动状态。实际上,它可能与ThreadPool
线程有关。
如果你想要一个特定的优先级线程,那么使用你自己的Thread
对象 - 但我不建议这样做正常......
此外 - “背景”并不意味着“空闲时”。即使在单核心机器上,您也可能会看到两个线程获得尽可能多的rnutime(如果他们想要的话)。在多核上更是如此。
答案 3 :(得分:1)
您可能希望查看此工作线程实现。它具有受保护的构造函数,用于指定线程的名称,线程的优先级以及线程是否是后台线程。