.net 当添加数千行时,应用程序变得无响应

.net 当添加数千行时,应用程序变得无响应,.net,winforms,multithreading,datagridview,.net,Winforms,Multithreading,Datagridview,我有一个windows窗体应用程序,它创建一个后台线程来搜索文件,并将匹配的文件名添加到DataGridView。后台线程使用BeginInvoke将行添加到DataGridView,如果后台线程不返回数千个结果,则一切正常。即使后台线程处理数千个文件,UI也可以正常工作,除非它尝试将数千行添加到DataGridView 我试着一个接一个地添加行,缓冲它们,然后一次添加100行。但是,应用程序UI始终没有响应。后台进程的工作速度比UI线程快,并且总是有新行要添加到DataGridView 我甚至

我有一个windows窗体应用程序,它创建一个后台线程来搜索文件,并将匹配的文件名添加到DataGridView。后台线程使用BeginInvoke将行添加到DataGridView,如果后台线程不返回数千个结果,则一切正常。即使后台线程处理数千个文件,UI也可以正常工作,除非它尝试将数千行添加到DataGridView

我试着一个接一个地添加行,缓冲它们,然后一次添加100行。但是,应用程序UI始终没有响应。后台进程的工作速度比UI线程快,并且总是有新行要添加到DataGridView

我甚至尝试了Application.DoEvents(在UI线程中),但也没有帮助

有什么想法吗?我可以在不增加后台线程延迟的情况下修复它吗


提前感谢

尝试使用数据虚拟化:

尝试使用数据虚拟化:

一种方法是让主线程创建一个
BlockingCollection
,作为后台线程可以添加字符串的队列。后台线程完成添加后,将调用
completedadding

UI线程还创建了一个以一定频率触发的计时器(可能是您通过实验确定的)。计时器的
appeased
事件查看队列中是否有任何内容,如果有,则删除一项并将其添加到
DataGridView
。当计时器的
已过
事件看到队列的
IsComplete
属性为
True
时,它停止并处理计时器


如果你的计时器不太快,那么你的UI就会保持响应,你也不必费心给后台线程增加延迟。

一种方法是让主线程创建一个
BlockingCollection
,作为后台线程可以添加字符串的队列。后台线程完成添加后,将调用
completedadding

UI线程还创建了一个以一定频率触发的计时器(可能是您通过实验确定的)。计时器的
appeased
事件查看队列中是否有任何内容,如果有,则删除一项并将其添加到
DataGridView
。当计时器的
已过
事件看到队列的
IsComplete
属性为
True
时,它停止并处理计时器


如果您的计时器运行速度不太快,那么您的UI将保持响应速度,并且您不必费心在后台线程中添加延迟。

确保在添加所有新行之前和之后分别调用
SuspendLayout()
resumellayout()
。在添加所有行之前,如果不调用
SuspendLayout
DataGridView
将在每个添加的行之后重新绘制自身,这将使速度减慢一点。

确保在添加所有新行之前和之后分别调用
SuspendLayout()
resumellayout()
。在添加所有行之前,如果不调用
SuspendLayout
DataGridView
将在每个添加的行之后重新绘制自身,这将使速度减慢一点。

看起来使用Invoke而不是BeginInvoke来添加行是最简单的解决方案。它会稍微减慢后台线程的速度,但会防止UI变得无响应。 由于您没有向后台线程添加预定义的延迟,我认为可以接受稍微降低后台线程的速度,只让UI线程跟上。 在使用BeginInvoke时,使用SuspendLayout和ResumeLayout也没有帮助。
我还没有尝试共享行的虚拟模式,但这可能也有帮助

使用Invoke而不是BeginInvoke来添加行似乎是最简单的解决方案。它会稍微减慢后台线程的速度,但会防止UI变得无响应。 由于您没有向后台线程添加预定义的延迟,我认为可以接受稍微降低后台线程的速度,只让UI线程跟上。 在使用BeginInvoke时,使用SuspendLayout和ResumeLayout也没有帮助。
我还没有尝试共享行的虚拟模式,但这可能也有帮助

我的问题似乎是,如果我添加了10000行,每次添加一行时,滚动条都会重新绘制自己。我通过在填充之前将datagridview的滚动条设置为“无”,然后在填充之后恢复,解决了这个问题,如下所示:

滚动条=this.ScrollBars; this.ScrollBars=System.Windows.Forms.ScrollBars.None

。。。在此处填充(我有一个覆盖的DataGridView控件)

this.ScrollBars=条


在添加数千行的情况下,由于某些原因,SuspendLayout不起作用。

我的问题似乎是,如果添加10000行,每次添加一行时,滚动条都会重新绘制。我通过在填充之前将datagridview的滚动条设置为“无”,然后在填充之后恢复,解决了这个问题,如下所示:

滚动条=this.ScrollBars; this.ScrollBars=System.Windows.Forms.ScrollBars.None

。。。在此处填充(我有一个覆盖的DataGridView控件)

this.ScrollBars=条


在添加数千行的情况下,由于某些原因,SuspendLayout不起作用。

让BGW以比UI更快的速度生成结果有什么意义?或者让用户阅读它们?你在浪费内存而没有任何好处。让BGW产生结果的速度快于UI显示结果的速度有什么意义?或者让用户阅读它们?你在浪费内存而没有任何好处。使用Control.Invoke而不是BeginInvoke将更容易做到这一点。使用Control.Invoke而不是BeginInvoke将更容易做到这一点