ShowDialog занимает слишком много времени на Windows Server 2016 - PullRequest
0 голосов
/ 26 сентября 2018
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

}

Время, прошедшее между запуском form.ShowDialog() и моментом, когда обработчик события загрузки myForm_Load повышался:

  1. в Windows Server 2008R2 ~ 250 мс
  2. вклWindows Server 2016 ~ 4500мс

Аппаратное обеспечение:

  1. Windows Server 2008R2 Физический сервер 2,8x12 ГГц
  2. Windows Server 2016 Виртуальная машина Hyper-V 2,4x20 ГГц

Структура MyForm: TableLayoutPanel с Dock==DockStyle.Fill.У него около двух десятков TextBox, ComboBox, Label и т. Д. Еще два Button, один TabControl и один DataGridView.И два экземпляра моего производного UserControl.

Свойство DoubleBuffered MyForm установлено в true.Я попробовал false, но скорость не ускорилась.
Что занимает столько времени?Что еще можно попробовать?


Обновление

Код обработчиков событий был профилирован с помощью моего собственного профилировщика на основе StopWatch.И тогда я знаю, что пауза состоит из двух частей.Каждый раз, когда он появляется до того, как MyUserControl.SelectedValue вызывает сеттер.Возможно, важно, что SelectedValue является привязываемым свойством класса MyUserControl с [System.ComponentModel.DefaultBindingProperty("SelectedValue")]

Кроме того, я знаю, удаляю ли я оба экземпляра UserControl, MyForm будет отображаться быстро.Тем не менее, я не знаю, что именно тратить столько времени.


Обновление 2

Я нашел "преступник" .Это ComboBox с большим количеством элементов в источнике данных.В настоящее время могу представить 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...