Почему элементы управления WinForms / WPF не используют Invoke для внутреннего использования? - PullRequest
5 голосов
/ 09 февраля 2011

Я понимаю, почему элементы управления GUI имеют сходство потоков.

Но , почему элементы управления не используют внутренний вызов в своих методах и свойствах?

Теперь вам нужно сделать что-то подобное, чтобы обновить TextBox значение:

this.Invoke(new MethodInvoker(delegate()
{
    textBox.Text = "newValue";
}

При использовании только textBox.Text = "newValue"; будет достаточно представить ту же логику.

Все, что нужно сделать, это изменить textBox.Text логику из этого (псевдокод):

public string Text
{
    set
    {
        if(!this.InvokeRequired)
            // do the change logic
        else
            throw new BadThreadException();
    }
}

К этому:

public string Text
{
    set
    {
        if(!this.InvokeRequired)
            // do the change logic
        else
            this.Invoke(new MethodInvoker(delegate()
            {
                // do the change logic
            }
    }
}

То же самое касается геттеров и методов.

Я, конечно, не предлагаю удалять Invoke / BeginInvoke, я просто спрашиваю, почему элементы управления не выполняют необходимое переключение потоков самостоятельно, а не выдают исключение.

Ответы [ 3 ]

9 голосов
/ 09 февраля 2011

Я думаю, что таким образом API заставляет разработчиков принимать четкие решения и избегать непреднамеренных ошибок в программировании. Вот несколько проблем, с которыми я мог бы столкнуться сразу:

1. Непреднамеренная блокировка резьбы . Если вы пишете в свойство, вызывающему потоку придется блокировать, пока сообщение не будет обработано потоком пользовательского интерфейса. И если вызывающему потоку принадлежит ресурс, который поток пользовательского интерфейса может захотеть получить, вы получите тупик, который трудно отладить (вызывающий поток удерживает ресурс и ждет, пока сообщение обрабатывается потоком пользовательского интерфейса; поток пользовательского интерфейса ожидает освобождения ресурса ).

2. Неожиданные сюрпризы . Если мы сделаем операции записи неявно асинхронными, мы столкнемся с ситуацией, когда читатель никогда не должен ожидать, что значения всегда будут актуальными.

3. Влияние на производительность . Если вы напишите интенсивный алгоритм, который неявно использует диспетчеризацию пользовательского интерфейса, вы получите действительно низкую производительность и можете обвинять разработчиков фреймворка. В конце концов, вы написали сортировку, которая должна выполняться в O (n), но по какой-то причине требуется несколько веков.

2 голосов
/ 09 февраля 2011

Ну, если кто-то из разработчиков или разработчиков из фреймворка не ответит, об этом можно только догадываться, но самое очевидное, что, по крайней мере, мое мнение, это сложность .Добавление логики переключения потоков во все соответствующие места всех элементов управления приведет к огромному увеличению их сложности (просто представьте, что все тестирование необходимо для повсеместной проверки поведения).Вероятно, это просто не стоило бы усилий, так что работа передается пользователям элементов управления (нам, тем), которым необходимо пройти этот небольшой дополнительный тур в тех случаях, когда это необходимо.

0 голосов
/ 09 февраля 2011

Согласитесь с @Code Grey, Windows выдает исключение вызовов Cross Thread, если другой поток обновляет элемент управления. Однако вы можете сделать потокобезопасные звонки - http://msdn.microsoft.com/en-us/library/ms171728(v=VS.100).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...