Чистые шаблоны Invoke?

2

Сейчас у меня есть приложение 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);

Есть ли более чистый способ получить эти значения из отдельного потока?

Теги:
multithreading

2 ответа

2
Лучший ответ

Предполагая, что вы хотите использовать проект с резьбой (возможно, вы хотите, чтобы потоки фона сообщали о частичных результатах пользовательского интерфейса при их запуске?), если у вас есть С# 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 для операций, для которых не требуется возвращаемое значение.

4

короткий ответ

Не делайте этого; -)

длинный ответ

собирать параметры отчета из элементов интерфейса пользователя спереди (возможно, в малом классе) и передавать их в отчеты в фоновом потоке

Это устраняет вызовы перекрестных потоков для элементов управления пользовательского интерфейса и отделяет параметры отчета от пользовательского интерфейса

Ещё вопросы

Сообщество Overcoder
Наверх
Меню