9

我正在尝试在我正在开发的应用程序中使用 .NET Backgroundworker 对象。

互联网上的所有资料都说该对象在“后台”运行,但我无法确认该后台线程确实以“低优先级”模式运行。出现这个问题是因为在 Windows(我假设)中,后台任务可以在“正常”或“低于正常”或“低”优先级模式下运行。

在我的应用程序中,我尝试通过调用 ...

Thread.CurrentThread.Priority=ThreadPriority.Lowest

...

但这似乎没有效果。后台工作人员是否忽略此调用?

我想再解释一些:

我的应用程序是一个互联网客户端,它从室内收集有关温度、湿度等的实时数据,并使用

system.net.webclient.UploadValuesAsync(...)来电

我已经编写了应用程序,以便客户端 GUI 从腔室收集数据,为它们加上时间戳,然后将它们排队等待上传,就像这样

...

Synclock objlock
    debug.print("Queueing reading...")
    dataQ.Enque(reading)
End Synclock
...

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

......

当我运行程序时,我发现每当调用 UploadValuesAsync 时,调试窗口就会停止。我还添加了调试语句以随时查看队列中有多少读数。如果此任务真正以低优先级运行,我希望看到队列计数在获取数据时迅速增加,然后仅在前台空闲且未获取数据时减少。但这种情况并非如此。一旦将读数添加到队列中,它就会出列并上传。因此队列计数始终为 1 或 0!

我的方法有问题吗?我根本不应该使用后台工作者对象吗?

顺便说一句,这是在运行 Windows XP 的双核笔记本电脑中。

4

4 回答 4

16

只是补充一下 Jon 和 Marc 已经说过的话:

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

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

于 2009-02-07T20:53:08.173 回答
8

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

为此使用后台工作人员没有任何问题,但是入队/出队实际上应该只使用生产者/消费者队列,当您尝试在没有准备好的情况下出队时阻塞。

我在我的线程教程中有一个生产者/消费者队列的示例实现- 请参阅链接页面的大约一半。顺便说一句,您需要某种方式来告诉出队过程它已经完成。(例如,将空引用或其他特殊值排入队列。)该代码是在泛型之前编写的,但应该很容易更新。

于 2009-02-07T20:19:06.323 回答
3

它并没有声称是低优先级 - 背景意味着 a:不是 UI 线程,并且 b:它不会让进程保持活动状态。实际上,它可能与ThreadPool线程有关。

如果你想要一个特定的优先级线程,那么使用你自己的Thread对象 - 但我通常不会推荐这个......

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

于 2009-02-07T20:18:44.000 回答
1

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

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

于 2009-02-09T17:12:44.867 回答