2015-12-17 100 views
3

我在C#中使用BackgroundWorker性能出现了一个奇怪的问题。我有一个应用程序,其中使用BackgroundWorker来执行某些任务。 Basicaly任务如下:C#中BackgroundWorker的性能问题

public void simulate(Image imgSimulator) 
     { 
      simulador = new Simulator(imgSimulator); 
      simulador.setBackground(0); 
      Constants.finishSimulation = false; 
      BackgroundWorker bw = new BackgroundWorker(); 
      bw.DoWork += run; 
      bw.RunWorkerAsync(imgSimulator); 
     } 

public void run(object sender, DoWorkEventArgs e) 
     { 
      Image imgSimulator = (Image)e.Argument; 
      bool clear; 
      foreach (Program p in programs) 
      { 
       Resource r = p.getResource(0); 
       clear = true; 
       if (r is Text) 
       { 
        Text t = (Text)r; 
        clear = t.getClearPrev() == 1; 
       } 
       if (!clear) 
       { 
        simulador.setBackground(FontBitmap.COLOR_BLACK); 
       } 
       p.execute(simulador, imgSimulator); 
       if (Constants.finishSimulation) 
       { 
        break; 
       } 
      } 

     } 

在上面的代码的主要职能是执行:

public void execute(Simulator simulador, System.Windows.Controls.Image imgSimulator) 
     { 
      long now = DateTime.Now.Ticks/10000; 
      long current = DateTime.Now.Ticks/10000; 
      while (true) 
      { 
       current = DateTime.Now.Ticks/10000; 
       if (current - now >= 1) 
       { 
        App.Current.Dispatcher.Invoke((Action)(() => 
        { 
         ((MainWindow)System.Windows.Application.Current.MainWindow).Title = "" + Constants.index++; 

        })); 
        now = DateTime.Now.Ticks/10000; 
       } 
      } 
     } 

我已经修改了执行功能调试的目的,现在它改变主窗口的标题。

的问题是,在我的电脑应用程序运行正常,但我想它在另一台PC和标题不会以相同的速率更新。

这里有一些数据(我已经改变了做这个测试的唯一的事情就是数10000)

如果我改变10000〜1000000在我的电脑应用程序需要30秒钟达到300(在窗口标题栏),同样的情况发生在另一台电脑上。 如果我改变10000到100000在我的电脑应用程序需要30秒到达3000(在窗口标题栏),但在另一台电脑需要47秒到达3000

我注意到的其他事情是,如果我打开另一个C#应用程序(WPF),并将鼠标移到其控件上(或将焦点放在文本框上),该应用程序正确运行(以与它运行速度相同的速度运行)。

我的电脑和其他电脑的唯一区别是我安装了Visual Studio 2013。

可能是什么问题?

谢谢。

+0

如果调用['RenderCapability.Tier'](https://msdn.microsoft.com/en-us/library/system.windows.media.rendercapability.tier(V = VS.100)的.aspx)上两个系统,你有相同的价值吗?此外,DateTime的准确性可能因系统而异。如果您将代码切换到使用“Stopwatch”,它是否会更加一致(如果两个层次与第一个问题相同)? –

+0

我假设你的意思是你的意思是“10000”的示例代码中的“100000”? – RandomEngy

+0

是的,我想说的10000 – RdlP

回答

10
if (current - now >= 1) 

这不会做你希望的事情,DateTime.Now不会更新每一毫秒。默认情况下,它每秒更新64次,每15.625毫秒一次。所以你的Constants.index的增量不能超过每秒64。

但其他进程和驱动程序可以通过调用timeBeginPeriod改变更新率()。例如,浏览器可以将其更改为10毫秒,这是一个令GIF动画的快乐数字。现在你会每秒增加一百次Constants.index。

而这正是你所看到的:15.625/10 * 30秒= 47秒。

可以通过从提升的命令提示运行powercfg /energy看到一台机器上的活动率。生成的报告显示标题“平台计时器分辨率”下的数字。

必须避免服用对更新速度的依赖。

+0

在它运行正确,它说的PC: '当前计时器分辨率(100纳秒为单位)最大周期定时器(100米纳秒为单位)\t 156001' 在运行在PC慢说: '当前计时器分辨率(100 ns单位)156000' 如何更改该值? – RdlP

+1

Hmya,现在你应该知道它是“运行缓慢的电脑”,实际上它是正确运行的电脑。但很高兴看到我的猜测已经结束,您确实喜欢在10毫秒内运行平台计时器。有多种方法可以解决这个问题,但正如我所指出的,您也可以调用timeBeginPeriod()来更改它。你会在[本文]中找到pinvoke声明(http://stackoverflow.com/a/16632882/17034)。切记,只要你这样做,你的模拟速度永远不会超过每秒千次。 –