我一直在调查我的应用中的性能问题,归结为调用Invoke逐渐变长的时间。我正在使用System.Diagnostics.Stopwatch为Invoke调用本身计时,当它在20ms开始时,几百次调用后它大约是4000ms。记录显示时间稳定增加(首先是每次呼叫约2ms,然后是~100ms或更长)。我有三个Invokes,都表现出相同的行为。
我正在加载医学图像,我需要保持我的UI响应,这样做,因此使用后台工作者,我可以加载和处理图像,但一旦加载,他们需要添加到man UI for用户要看。
在我尝试加载超过800张图像的研究之前,这个问题并没有出现。以前我的测试集大约有100张图片,总大小从400MB到16GB不等。问题集只有2GB大小,接近10分钟接近50%,16GB集合总共加载约30s,因此排除了总图像大小问题。作为参考,我的开发机器有32GB RAM。我通过评论整个事情来确保它不是被调用方法的内容。
我想了解的是,如何调用逐步增加的时间?这实际上是一件事吗?我的调用堆栈没有变得越来越深,线程数是否一致,导致这种情况消耗了多少资源?我错过了什么!?
public void UpdateThumbnailInfo(Thumbnail thumb, ThumbnailInfo info)
{
if (InvokeRequired)
{
var sw = new Stopwatch();
sw.Start();
Invoke((Action<Thumbnail, ThumbnailInfo>) UpdateThumbnailInfo, thumb, info);
Log.Debug("Update Thumbnail Info Timer: {Time} ms - {File}", (int) sw.ElapsedMilliseconds, info.Filename);
}
else
{
// Do stuff here
}
}
答案 0 :(得分:1)
看起来你正在从另一个线程调用UpdateThumbnailInfo
。如果是这样,那么这就是预期的行为。发生的事情是你在UI线程上排队数百个任务。对于每个加载的图像,UI需要做很多事情,因此随着图像数量的增加,整体操作变得缓慢。
您可以做的一些事情:
*使用BeginInvoke
代替Invoke
。由于您的函数是void类型,因此您不需要EndInvoke
*使用SuspendLayout
和ResumeLayout
来阻止用户界面逐步更新,而是在加载所有图片时更新所有内容。