Открыть диалог из рабочего потока
Почему при методе Show() блокируется форма, а при методе ShowDialog() нет
Так блокируется:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
Form forma = new();
forma.Height = 500;
forma.Width = 500;
forma.Show();
});
}
А так не блокируется:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
Form forma = new();
forma.Height = 500;
forma.Width = 500;
forma.ShowDialog();
});
}
Ответы (2 шт):
А нужно мне, чтобы рабочий поток отправил команду главному потоку отобразить кастомную форму или же как то отобразить прям в нём xD В это окно пользователь должен ввести данные и эти данные нужно считать при нажатии кнопки в тот самый рабочий поток
Task.Run(() =>
{
int variable = 0;
DialogResult result = default;
// ... работа
this.Invoke((Action)(() =>
{
Form2 forma = new();
forma.Height = 500;
forma.Width = 500;
result = forma.ShowDialog(this);
variable = forma.ResultVariable;
}));
if (result == DialogResult.OK)
{
// ... работа
}
});
this.Invoke остановит рабочий поток, пока открытый диалог не будет закрыт.
Объявите публичные поля или свойства в открываемом диалоге или определите метод, возвращающий необходимые значения из формы. Или вообще инкапсулируйте данные в экземпляре класса для данных.
А нужно мне ... отобразить кастомную форму ... В это окно пользователь должен ввести данные и эти данные нужно считать при нажатии кнопки в тот самый рабочий поток
То есть на время показа формы вычисления в потоке прекращаются до тех пор, пока не будут введены данные. Следовательно, это можно реализовать как-то так:
Task.Run(() =>
{
// какие-то вычисления
});
Form forma = new();
// ...
Task.Run(() =>
{
// продолжение вычислений
});
Вот как это может выглядеть реально:
private async void Button1_Click(object sender, EventArgs e)
{
var partialResult = await Task.Run<int>(() =>
{
return 42;
});
var form = new Form();
var nud = new NumericUpDown { Parent = form };
form.Text = partialResult.ToString();
form.ShowDialog();
var value = (int)nud.Value;
var result = await Task.Run<int>(() =>
{
// продолжение вычислений
return partialResult * value;
});
Text = result.ToString();
}