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
повышался:
- в Windows Server 2008R2 ~ 250 мс
- вклWindows Server 2016 ~ 4500мс
Аппаратное обеспечение:
- Windows Server 2008R2 Физический сервер 2,8x12 ГГц
- 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);
}
}