C# 如何解决UI线程上的内存分配问题,而不是命令行上的问题?

C# 如何解决UI线程上的内存分配问题,而不是命令行上的问题?,c#,performance,user-interface,memory,backgroundworker,C#,Performance,User Interface,Memory,Backgroundworker,我编写了一个算法(函数),从列表中读入大量文件,对这些文件进行操作和聚合,然后存储为单个文件。这可以很好地处理每个文件,处理时间不超过一秒半 为了改善用户体验,我创建了一个简单的GUI来准备算法(输入文件列表、输出文件位置和处理选项等)。这个很好用 但是,该算法在UI线程(Windows窗体应用程序)上通过命令行线程(控制台应用程序)执行的时间要长得多。我找不到原因的解释。命令行执行时间与文件数接近线性关系。然而,UI线程或BackgroundWorker线程的执行是非常非线性的,并且很快就会变

我编写了一个算法(函数),从列表中读入大量文件,对这些文件进行操作和聚合,然后存储为单个文件。这可以很好地处理每个文件,处理时间不超过一秒半

为了改善用户体验,我创建了一个简单的GUI来准备算法(输入文件列表、输出文件位置和处理选项等)。这个很好用

但是,该算法在UI线程(Windows窗体应用程序)上通过命令行线程(控制台应用程序)执行的时间要长得多。我找不到原因的解释。命令行执行时间与文件数接近线性关系。然而,UI线程或BackgroundWorker线程的执行是非常非线性的,并且很快就会变得太慢而没有用处。见下表。(我在2小时后终止了100文件的运行)

文件1、3、5、13、20的数量
命令行执行时间1s、4s、7s、19s、29s
UI BackgroundWorker执行时间1秒、7秒、22秒、309秒、441秒

我认为这与我用来执行处理的BackgroundWorker类有关,但是在移除BackgroundWorker并直接从按钮上调用函数时,会导致速度更慢(5个文件82秒(并导致UI锁定))

我现在已经创建了一个独立的静态测试函数,其中散布着秒表,用于性能测试和发现问题

每增加一个文件,就会有一件事情变得越来越慢

stopwatches[21].Start();
byte[] canData = reader.ReadBytes(8);
stopwatches[21].Stop();
“阅读器”是二进制阅读器。这被用作简单文件,正在处理ZipArchiveEntry文件

其他突出显示为慢的代码行始终是内存分配,可以是“new”语句,也可以是List.Add函数

我对二进制读取器的理解涉及到它们缓冲传入的信息,从而分配内存。因此,我认为这是一个记忆问题。为了支持这一点,观察任务管理器UI线程/BackgroundWorker比命令行版本使用的内存要多得多。我怀疑性能会以非线性方式下降,因为我的机器开始交换


UI(Windows窗体应用程序)线程上的内存分配有什么不同?当从命令行(控制台应用程序)运行时,我应该如何调整代码以相同方式执行?

故障查找

在创建了一个与命令行(新的普通UI)一样快的工作UI之后,我开始寻找我的应用程序性能不佳的原因,我系统地删除了代码、回调、方法、数据,最终删除了所有组件,但毫无帮助。我现在有两段相同的代码,一段工作正常,一段不工作。。。所以我系统地对每个项目文件夹中的文件进行了区分,试图理解重要的区别(忽略名称更改等),所以我发现了我认为可能存在的问题。然后我在Visual Studio外部更改了文件,重新生成并运行。。。表演也不错。成功,发现错误

答案

故障在csproj文件中

<Reference Include="System.Core">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>

3.5
3.5
3.5
我将其修改为以下内容

<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />

注:两人都有

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
v4.5
另外:我仍然无法在Visual Studio中找到设置此选项的位置,在查找要检查的文件之前,我确实检查了这两组属性,但即使在找到问题后,它仍然对我在Visual Studio中隐藏

我相信这是因为我从从VisualStudio2008升级的表单复制了表单,而升级过程一定是错误完成的。使用Visual Studio 2015升级


一个值得注意的。。。最后一个问题。现在我是否应该更新标题(主要问题)以更好地阐明实际问题?

故障查找

在创建了一个与命令行(新的普通UI)一样快的工作UI之后,我开始寻找我的应用程序性能不佳的原因,我系统地删除了代码、回调、方法、数据,最终删除了所有组件,但毫无帮助。我现在有两段相同的代码,一段工作正常,一段不工作。。。所以我系统地对每个项目文件夹中的文件进行了区分,试图理解重要的区别(忽略名称更改等),所以我发现了我认为可能存在的问题。然后我在Visual Studio外部更改了文件,重新生成并运行。。。表演也不错。成功,发现错误

答案

故障在csproj文件中

<Reference Include="System.Core">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>

3.5
3.5
3.5
我将其修改为以下内容

<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />

注:两人都有

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
v4.5
另外:我仍然无法在Visual Studio中找到设置此选项的位置,在查找要检查的文件之前,我确实检查了这两组属性,但即使在找到问题后,它仍然对我在Visual Studio中隐藏

我相信这是因为我从从VisualStudio2008升级的表单复制了表单,而升级过程一定是错误完成的。使用Visual Studio 2015升级


一个值得注意的。。。最后一个问题。我现在是否应该更新标题(主要问题)以更好地阐明实际问题?

您是否对UI进行了任何更新,以便在处理文件时让用户了解最新的进度?嗨,马克,我根本没有更新UI线程。我是,我认为这是问题所在,我已经把它撕掉了,现在我的测试用例没有了。这可能是因为UI版本中存在
SynchronizationContext
——你做过任何异步处理吗?嗨,卢卡斯,我撕掉了太多了,我只剩下表单上的一个按钮。(我已经为此奋斗了好几天了)。我在哪里可以找到是否有SynchronizationContext,或者知道是否有