Сейчас у меня есть приложение Windows (С#), которое выплескивает длинные отчеты. Каждый отчет захватывает некоторую информацию из пользовательского интерфейса, чтобы ограничить отчеты. Конечно, создание отчета происходит в фоновом потоке, и мне нужно правильно вызвать различные элементы управления, чтобы получить такие вещи, как выбранные индексы и значения. Но я не думаю, что мой код выглядит хорошо и надеялся, что будет лучшая модель. Поскольку запросов на управление очень много, я сделал общие делегаты для каждого типа, который будет возвращен:
private delegate string StringDelegate();
private delegate int IntDelegate();
Далее, существуют различные экземпляры этих делегатов:
private StringDelegate GetYearSelectedItem = new StringDelegate(cmbYearAsync);
YearAsync выглядит следующим образом:
private string cmbYearAsync() {
return cmbYear.SelectedItem.ToString();
}
И, наконец, в коде, который находится в фоновом потоке, вот как я получаю значения:
cmbYear.Invoke(GetCmbYearSelectedItem);
Есть ли более чистый способ получить эти значения из отдельного потока?
Предполагая, что вы хотите использовать проект с резьбой (возможно, вы хотите, чтобы потоки фона сообщали о частичных результатах пользовательского интерфейса при их запуске?), если у вас есть С# 3, вы можете немного его немного подправить. Некоторые люди находят способ расширения, как этот полезный:
public static class ControlExtensions
{
public static T Invoke<T>(this Control ctrl, Func<T> func)
{
if (ctrl.InvokeRequired)
return (T) ctrl.Invoke(func);
return func();
}
}
Кроме того, чтобы проверить, должен ли вызов быть настроен, он также делает параметр делегата параметрическим. Поэтому вы можете написать:
string selected = comboBox1.Invoke(() => comboBox1.SelectedItem.ToString());
Не нужно предварительно объявлять все это. Просто напишите обычный код, который вы напишете, но внутри этого лямбда-шаблона.
Вы можете написать аналогичный метод расширения, который принимает Action
вместо Func<T>
и возвращает void
для операций, для которых не требуется возвращаемое значение.
Не делайте этого; -)
собирать параметры отчета из элементов интерфейса пользователя спереди (возможно, в малом классе) и передавать их в отчеты в фоновом потоке
Это устраняет вызовы перекрестных потоков для элементов управления пользовательского интерфейса и отделяет параметры отчета от пользовательского интерфейса