.NET Backgroundworker对象的线程优先级

时间:2009-02-07 20:10:54

标签: .net multithreading backgroundworker

我正在尝试在我正在开发的应用程序中使用.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的双核笔记本电脑。

4 个答案:

答案 0 :(得分:14)

只是添加Jon和Marc已经说过的话:

后台线程没有较低的优先级。前台线程和后台线程之间的区别在于,一旦不再运行前台线程,CLR将关闭进程。线程池线程是后台线程。

您实际上可以设置线程池线程的优先级,但是由于您无法控制哪个线程池线程实际运行您的任务,因此不建议这样做。如果需要特定优先级的线程,则应使用Thread类型创建它们,并根据需要在实例上设置优先级。

答案 1 :(得分:7)

是的,您的方法有问题 - 当队列为空时,您基本上是紧密循环。无论线程优先级是什么,这都是一个坏主意。

使用后台工作程序没有任何问题,但是入队/出队应该只使用生产者/消费者队列,当你没有准备就绪时,当你试图出队时会阻塞它。

我有一个生产者/消费者队列in my threading tutorial的示例实现 - 看看链接页面的一半。顺便说一下,你会想要一些方法告诉出列的过程它已经完成了。 (例如,将空引用或其他特殊值排入队列。)该代码是在泛型之前编写的,但它应该很容易更新。

答案 2 :(得分:3)

它并不声称是低优先级 - 后台意味着:不是UI线程,而b:它不会使进程保持活动状态。实际上,它可能与ThreadPool线程有关。

如果你想要一个特定的优先级线程,那么使用你自己的Thread对象 - 但我不建议这样做正常......

此外 - “背景”并不意味着“空闲时”。即使在单核心机器上,您也可能会看到两个线程获得尽可能多的rnutime(如果他们想要的话)。在多核上更是如此。

答案 3 :(得分:1)

您可能希望查看此工作线程实现。它具有受保护的构造函数,用于指定线程的名称,线程的优先级以及线程是否是后台线程。

http://devpinoy.org/blogs/jakelite/archive/2008/12/20/threading-patterns-the-worker-thread-pattern.aspx