C# 中 BackgroundWorker 的性能问题
Performance issue on BackgroundWorker in C#
我在 C# 中遇到 BackgroundWorker 性能的奇怪问题。我有一个应用程序,除其他外,它使用 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;
}
}
}
上面代码中的主要函数是execute:
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;
}
}
}
我已经修改了执行函数以进行调试,现在它更改了主要 window 标题。
问题是应用程序在我的电脑上运行正常,但我在另一台电脑上试过,标题没有以相同的速度更新。
这里有一些数据(我为做这个测试唯一改变的是数字 10000)
如果我在我的电脑上将 10000 更改为 1000000,应用程序需要 30 秒才能达到 300(在 window 标题栏中),而另一台电脑也会发生同样的情况。
如果我在我的电脑中将 10000 更改为 100000,应用程序需要 30 秒才能达到 3000(在 window 标题栏中),但在另一台电脑中需要 47 秒才能达到 3000
我注意到的另一件事是,如果我打开另一个 C# 应用程序 (WPF) 并将鼠标移到它们的控件上(或聚焦一个 TextBox),该应用程序将正确运行(与它在我的应用程序中运行的速度相同)电脑)。
我的电脑和其他电脑的唯一区别是我安装了 Visual Studio 2013。
可能是什么问题?
谢谢。
if (current - now >= 1)
这并没有达到您希望的效果,DateTime.Now 并不是每毫秒更新一次。默认情况下,它每秒更新 64 次,每 15.625 毫秒更新一次。所以你的 Constants.index 每秒不能超过 64。
但是其他进程和驱动程序可以通过调用 timeBeginPeriod() 来更改该更新率。例如,浏览器很容易将其更改为 10 毫秒,这是动画 gif 的一个快乐数字。现在你将 Constants.index 每秒递增一百次。
这正是您所看到的:15.625 / 10 * 30 秒 = 47 秒。
您可以在提升的命令提示符下通过 运行 powercfg /energy
查看机器上的活动率。生成的报告显示标题 "Platform Timer Resolution".
下的数字
您必须避免依赖更新率。
我在 C# 中遇到 BackgroundWorker 性能的奇怪问题。我有一个应用程序,除其他外,它使用 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;
}
}
}
上面代码中的主要函数是execute:
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;
}
}
}
我已经修改了执行函数以进行调试,现在它更改了主要 window 标题。
问题是应用程序在我的电脑上运行正常,但我在另一台电脑上试过,标题没有以相同的速度更新。
这里有一些数据(我为做这个测试唯一改变的是数字 10000)
如果我在我的电脑上将 10000 更改为 1000000,应用程序需要 30 秒才能达到 300(在 window 标题栏中),而另一台电脑也会发生同样的情况。 如果我在我的电脑中将 10000 更改为 100000,应用程序需要 30 秒才能达到 3000(在 window 标题栏中),但在另一台电脑中需要 47 秒才能达到 3000
我注意到的另一件事是,如果我打开另一个 C# 应用程序 (WPF) 并将鼠标移到它们的控件上(或聚焦一个 TextBox),该应用程序将正确运行(与它在我的应用程序中运行的速度相同)电脑)。
我的电脑和其他电脑的唯一区别是我安装了 Visual Studio 2013。
可能是什么问题?
谢谢。
if (current - now >= 1)
这并没有达到您希望的效果,DateTime.Now 并不是每毫秒更新一次。默认情况下,它每秒更新 64 次,每 15.625 毫秒更新一次。所以你的 Constants.index 每秒不能超过 64。
但是其他进程和驱动程序可以通过调用 timeBeginPeriod() 来更改该更新率。例如,浏览器很容易将其更改为 10 毫秒,这是动画 gif 的一个快乐数字。现在你将 Constants.index 每秒递增一百次。
这正是您所看到的:15.625 / 10 * 30 秒 = 47 秒。
您可以在提升的命令提示符下通过 运行 powercfg /energy
查看机器上的活动率。生成的报告显示标题 "Platform Timer Resolution".
您必须避免依赖更新率。