首页 > 解决方案 > ShowDialog 在 Windows Server 2016 上花费了太多时间

问题描述

var form = new MyForm(someargs);
//400 ms
form.ShowDialog();
...
private void myForm_Load(object sender, EventArgs e)
{
   //4500 ms since form.ShowDialog() on Windows 2016

}

从启动到Load 事件处理程序引发form.ShowDialog()的那一刻之间经过的时间:myForm_Load

  1. 在 Windows Server 2008R2 上 ~250ms
  2. 在 Windows Server 2016 上 ~4500ms

硬件:

  1. Windows Server 2008R2 2.8x12 GHz 物理服务器
  2. Windows Server 2016 2.4x20 GHz Hyper-V 虚拟机

MyForm 的结构是: TableLayoutPanel带有Dock==DockStyle.Fill. 它有大约两个十个TextBoxComboBoxLabel。然而,两个Button,一个TabControl和一个DataGridView。还有我派生的 UserControl 的两个实例。

MyForm 的DoubleBuffered属性设置为true. 我试过false了,但速度没有加快。
什么需要这么多时间?我还能尝试什么?


更新

事件处理程序的代码已使用我自己的基于 StopWatch 的分析器进行了分析。然后我知道暂停包含两个部分。每次它出现在MyUserControl.SelectedValuesetter 调用之前。也许这很重要,这SelectedValueMyUserControl类的可绑定属性[System.ComponentModel.DefaultBindingProperty("SelectedValue")]

另外,我知道如果我删除我的两个 UserControl 实例 MyForm 将很快显示。但是,我不知道究竟是什么花费了这么多时间。


更新 2

我找到了“肇事者”。它是ComboBoxDataSource 中包含大量项目的项目。目前,我可以介绍MCVE

    ...
    private void button1_Click(object sender, EventArgs e)
    {
        var form = new MyForm(); //  76ms 2008R2;  123ms 2016
        form.ShowDialog();       //1820ms 2008R2;12440ms 2016
    }
}

public class MyForm : Form
{        
    private readonly ComboBox myComboBox = new ComboBox();
    public MyForm()
    {
        var manyItems = Enumerable.Range(1, 66_000)
            .Select(t => new
            {
                Key = t,
                Value1 = t.ToString(),
                Value2 = t.ToString() + t.ToString()
            })
            .ToList();
        myComboBox.DataSource = manyItems;
        myComboBox.ValueMember = "Key";
        myComboBox.DisplayMember = "Value2";
        this.Controls.Add(myComboBox);
    }
}

标签: c#winformswindows-server-2016

解决方案


推荐阅读