StackOverflowException用的DataGridView(StackOverflow

2019-08-05 12:28发布

这是一个奇数之一。 我有一个DataGridView 。 我设置它DataSourceList包含我自己的自定义类的对象。 有列表中的约50000项。 我定义我想说的是在设计可见,并设置列AutoGenerateColumns为false。

只要我设置了DataSource到我的名单,则立即无误。 我可以上下滚动,选择不同的行。 一切都是好的。 但是,当我滚动所有的方式下来,然后让窗口包含DataGridView失去焦点都冻结起来,而堆栈溢出这样经过短暂的:

System.Drawing.dll!System.Drawing.SafeNativeMethods.Gdip.GdipDeleteGraphics(System.Runtime.InteropServices.HandleRef graphics) + 0x2a bytes 
    System.Drawing.dll!System.Drawing.Graphics.Dispose(bool disposing) + 0x56 bytes 
    System.Drawing.dll!System.Drawing.Graphics.Dispose() + 0x12 bytes   
    System.Drawing.dll!System.Drawing.Font.GetHeight() + 0xc8 bytes 
    System.Drawing.dll!System.Drawing.Font.Height.get() + 0xb bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRow() + 0x44 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.Clone() + 0x44 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRowCollection.this[int].get(int index) + 0xa8 bytes   
    System.Windows.Forms.dll!System.Windows.Forms.DataGridView.DataGridViewAccessibleObject.GetChild(int index) + 0xbd bytes    
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x76 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    ...

出于某种原因, DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get()方法调用本身被遗忘。 整个堆栈似乎很奇怪,我。 为什么会Font.Height.get()调用过的DataGridViewRow

编辑:

有人问我的一些代码。 这是设计器生成的代码DataGridView和列:

    // 
    // dataGridView
    // 
    this.dataGridView.AllowUserToAddRows = false;
    this.dataGridView.AllowUserToDeleteRows = false;
    this.dataGridView.AllowUserToOrderColumns = true;
    this.dataGridView.AllowUserToResizeRows = false;
    this.dataGridView.BackgroundColor = System.Drawing.SystemColors.Window;
    this.dataGridView.BorderStyle = System.Windows.Forms.BorderStyle.None;
    this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
    this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
    this.Date,
    this.Type,
    this.Job,
    this.Mix,
    this.Entry});
    this.dataGridView.Location = new System.Drawing.Point(8, 96);
    this.dataGridView.Name = "dataGridView";
    this.dataGridView.ReadOnly = true;
    this.dataGridView.RowHeadersVisible = false;
    this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
    this.dataGridView.Size = new System.Drawing.Size(1152, 504);
    this.dataGridView.TabIndex = 10;
    this.dataGridView.SelectionChanged += new System.EventHandler(this.dataGridView_SelectionChanged);
    // 
    // Date
    // 
    this.Date.DataPropertyName = "FormattedTime";
    this.Date.HeaderText = "Date/Time";
    this.Date.Name = "Date";
    this.Date.ReadOnly = true;
    // 
    // Type
    // 
    this.Type.DataPropertyName = "FormattedType";
    this.Type.FillWeight = 60F;
    this.Type.HeaderText = "Type";
    this.Type.Name = "Type";
    this.Type.ReadOnly = true;
    this.Type.Width = 60;
    // 
    // Job
    // 
    this.Job.DataPropertyName = "Job";
    this.Job.FillWeight = 80F;
    this.Job.HeaderText = "Job No.";
    this.Job.Name = "Job";
    this.Job.ReadOnly = true;
    this.Job.Width = 80;
    // 
    // Mix
    // 
    this.Mix.DataPropertyName = "Mix";
    this.Mix.FillWeight = 80F;
    this.Mix.HeaderText = "Mix No.";
    this.Mix.Name = "Mix";
    this.Mix.ReadOnly = true;
    this.Mix.Width = 80;
    // 
    // Entry
    // 
    this.Entry.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
    this.Entry.DataPropertyName = "FormattedSummary";
    this.Entry.HeaderText = "Entry";
    this.Entry.Name = "Entry";
    this.Entry.ReadOnly = true;

当开始的时间,来填充网格视图,我只是做了:

dataGridView.DataSource = myList;

Answer 1:

固定

没有锁定在这个时候是已知的。

解决方法

禁用从控制面板中的服务面板Tablet PC输入服务 (又名tabtip.exe)。

细节

几个星期前,我接触过这个问题微软开发人员支持。 我用相对应的WinForms的团队支持工程师和我们想通了,这个问题在某些方面造成Accessibility.dll被加载到我的应用程序,每当微软的Tablet PC输入服务(tabtip.exe)正在运行。 这项服务是至少存在于所有的Windows 7企业版的安装,但如果你有一个平板电脑或安装过任何形式的笔输入设备的PC机上一般只运行。 我曾在过去使用的竹的Wacom数位板我的电脑上,因此为什么这个服务正在运行是有道理的。 请注意,这是确定的,无论是我用来填充方法DataGridView我设置的属性,也没有任何有什么关系的问题。

Accessibility.dll是微软库,允许某些外围设备(手写板,尤其是辅助设备)更容易互动,并获得约的形式和包含的形式控制的额外信息。 我不是100%肯定在这,但我相信,如果安装这样的外围该库自动加载到每个正在运行的Windows进程。

检查,我已经提供了转储后,微软的工程师通过该代码路径不解DataGridView决定走,发现Accessibility.dll是允许让它发生的罪魁祸首。 他坦言, DataGridView不应该这样做的,这似乎是对他们的最终问题。 然而,他无法连他的电脑和一个新鲜的Windows 7的虚拟机上都打开了Tablet PC输入服务后重现他的问题到底。 因此,尽管他能够找出导致问题的原因在我的电脑,他无法找到根本原因,因此无法进一步追求它的关键球员。

这可能是由于我的特殊手写板设备(Wacom公司)或别的东西都在一起。 它的未知数。 如果任何人遇到这个问题,请与我联系。 工程师邀请我与他联系,如果我是以往任何时候都能够缩小的原因。 现在,只需保持服务会阻止该问题。



Answer 2:

我曾经遇到过一个非常类似的一个的DataGridView的StackOverflowsException情景。

条件:

  1. 一个WinForm托管DataGridView控件。 DataGridView的性能只读和VirtualMode设置为true。
  2. VirtualMode的OnCellValueNeeded实现为每MSFT文档( http://msdn.microsoft.com/en-us/library/2b177d6d.aspx )
  3. 加载数据的相当大的量(15列×1×10 ^ 5行)
  4. 的datagridview的行为是正常的(即:的GUI,行和小区选择,垂直和水平滚动响应性),如果仅显示10列×30行的[300个细胞]。 当我最大化显示,使得显示单元的数量要大得多,在一个的DataGridView StackOverflowsException进行烧成。
  5. 我也有一个附加的Wacom数位板到我的电脑。
  6. 如果我停止Tablet PC输入服务(tabtip.exe)的问题就消失了

所以...在我的情况,事实上,弗兰克斯的解决方法是在正确的方向,并支持1 Tablet PC输入服务是罪魁祸首和2显示(有效)细胞在屏幕数量上具有效果的想法射击例外。



Answer 3:

首先,感谢@Frank Weindel用于指向这个奇怪的问题(只有微软能拿出这一点)。

对于那些谁不希望禁用“Tabtip.exe”为要求的一部分,说你的应用是平板电脑和唯一可能的输入法是Tabtip,有一个解决方法。

您可以在发生崩溃的情况下杀死Tabtip。 对我来说,这是当我行选择超过六万多件。 这是我做的。

Private Sub DataGridView1_Scroll(sender As Object, e As ScrollEventArgs) Handles DataGridView1.Scroll
    Call closeKeyboard()
End Sub

'When a user have to type something in textbox'
Private Sub Lookup_Tbox_MouseDown(sender As Object, e As MouseEventArgs) Handles Lookup_Tbox.MouseDown 
    Call OpenKeyboard()
End Sub

Public Sub OpenKeyboard()
    System.Diagnostics.Process.Start("tabtip.exe")
End Sub

Public Sub closeKeyboard()

    Dim proc() As System.Diagnostics.Process = Process.GetProcessesByName("tabtip")
    For i As Integer = 0 To proc.Length - 1
        proc(i).Kill()
    Next i
End Sub

希望它可以帮助别人快乐:) :)战斗



Answer 4:

我不是完全地理解乌尔问题的探析,但我觉得你的问题是datagridview的记忆缓慢

我有一个解决办法:1:打破datagridview的行插入喜欢的网页上显示在DataGridView中最大的100行和按钮或其他控制未来hundread单击它有助于减少乌尔显存2:上DataGridView的3启用双Buffred:使用Suspendlayout和简历布局功能轻易地吸引项目



Answer 5:

我有同样的问题的GridView与50K记录。 使用滚动条或简单地移动大量的记录引起DataGridView中StackOverflowsException。 看完上面我干脆停止屏幕键盘上的虚拟(我的屏幕是触摸屏)服务描述“启用触摸键盘和手写板笔墨功能”

一旦该停止的GridView的完美。



Answer 6:

我有确切的问题,如问题描述,阅读后在这里和我自己的运行实验,这解决了我的问题:

private void dataGridView1_Scroll(object sender, ScrollEventArgs ex)
{
    try
    {
         dataGridView1.Focus();
    }
    catch (Exception ex)
    {
         MessageBox.Show(ex.Message);
    }
}


文章来源: StackOverflowException with DataGridView