调用逐渐变慢
Invoke progressively getting slower
我一直在调查我的应用程序中的性能问题,归结为调用 Invoke 所花费的时间逐渐变长。我正在使用 System.Diagnostics.Stopwatch 来为 Invoke 调用本身计时,虽然它从 20 毫秒开始,但在数百次调用之后它大约是 4000 毫秒。日志记录显示时间稳步增加(最初每次调用增加约 2 毫秒,然后增加约 100 毫秒或更多)。我有三个调用,都表现出相同的行为。
我正在加载医学图像,我需要在加载过程中保持 UI 响应,因此使用后台工作程序,我可以在其中加载和处理图像,但一旦加载它们就需要添加到 man UI 供用户查看。
直到我尝试加载超过 800 张图像的研究时,问题才出现。之前我的测试集有大约 100 张图像,总大小从 400MB 到 16GB 不等。问题集的大小仅为 2GB,接近 50% 需要将近 10 分钟,而 16GB 的集加载总共需要约 30 秒,因此排除了图像总大小的问题。作为参考,我的开发机器有 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
}
}
您似乎是从另一个线程调用 UpdateThumbnailInfo
。如果是这样,那么这是预期的行为。正在发生的事情是您在 UI 线程上排队数百个任务。对于每个加载的图像,UI 需要做很多事情,因此随着图像数量的增加,整体操作会变慢。
您可以做的几件事:
* 使用 BeginInvoke
代替 Invoke
。由于您的函数是 void 类型,因此您不需要 EndInvoke
* 使用 SuspendLayout
和 ResumeLayout
来防止 UI 增量更新,而是在加载所有图像时更新所有内容。
我一直在调查我的应用程序中的性能问题,归结为调用 Invoke 所花费的时间逐渐变长。我正在使用 System.Diagnostics.Stopwatch 来为 Invoke 调用本身计时,虽然它从 20 毫秒开始,但在数百次调用之后它大约是 4000 毫秒。日志记录显示时间稳步增加(最初每次调用增加约 2 毫秒,然后增加约 100 毫秒或更多)。我有三个调用,都表现出相同的行为。
我正在加载医学图像,我需要在加载过程中保持 UI 响应,因此使用后台工作程序,我可以在其中加载和处理图像,但一旦加载它们就需要添加到 man UI 供用户查看。
直到我尝试加载超过 800 张图像的研究时,问题才出现。之前我的测试集有大约 100 张图像,总大小从 400MB 到 16GB 不等。问题集的大小仅为 2GB,接近 50% 需要将近 10 分钟,而 16GB 的集加载总共需要约 30 秒,因此排除了图像总大小的问题。作为参考,我的开发机器有 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
}
}
您似乎是从另一个线程调用 UpdateThumbnailInfo
。如果是这样,那么这是预期的行为。正在发生的事情是您在 UI 线程上排队数百个任务。对于每个加载的图像,UI 需要做很多事情,因此随着图像数量的增加,整体操作会变慢。
您可以做的几件事:
* 使用 BeginInvoke
代替 Invoke
。由于您的函数是 void 类型,因此您不需要 EndInvoke
* 使用 SuspendLayout
和 ResumeLayout
来防止 UI 增量更新,而是在加载所有图像时更新所有内容。