2009-02-07 181 views
8

我想在我正在开发的应用程序中使用.NET Backgroundworker对象。.NET Backgroundworker对象的线程优先级

所有互联网上的材料说,这个物体在“后台”运行,但无处我已能够证实,这个后台线程确实是一个“低优先级”模式运行。这个问题的产生是因为在Windows中(我认为)后台任务可以以“正常”或“低于正常”或“低”优先级模式运行。

在我的应用程序,我想我自己设定的优先级DoWork的函数内通过调用 ...

Thread.CurrentThread.Priority=ThreadPriority.Lowest 

...

但这似乎没有任何效果。背景工作者是否会忽略此调用?

我想解释些:

我的应用程序是一个互联网客户端收集温度的实时数据,从室内湿度等,并上传到一个网页(不是Web服务)使用

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的双核笔记本电脑。

回答

13

我想补充什么乔恩和马克已经说过:

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

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

3

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

如果你想有一个特定的优先级的线程,然后使用自己的Thread对象 - 但我不会建议甚至这通常...

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

+0

问题是,当后台线程调用UploadAsync,它似乎是阻止/减慢UI线程。我可以这样说,因为上传发生时调试语句会暂停。我怎样才能避免这种情况? – 2009-02-08 05:24:56

+0

你有多少核心?这项工作必须发生在某个地方...... – 2009-02-08 09:18:15

+0

这是一款双核笔记本电脑,采用Win XP。 – 2009-02-08 18:25:27

7

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

为此使用后台工作器没什么问题,但入队/出队应该只使用生产者/消费者队列,当你没有准备好任何东西时试图出队。

我有一个生产者/消费者队列的示例实现in my threading tutorial - 查看链接页面的大约一半。顺便说一下,您需要某种方式来告诉离职过程它已完成。 (例如,将空引用或其他特殊值排入队列。)该代码被写入预泛型,但应该易于更新。

+0

在您的示例中,您期望队列中有10个项目,并且消费者线程在将10个项目出列时会终止。就我而言,项目会在整个应用程序生命周期中添加到队列中(每秒大约10项),所以oWork不应该终止。那么还有什么可以做,但紧密的循环? – 2009-02-08 05:18:38