Замена InvokeRequired в WPF

Многие, кто занимается многопоточным программированием в Win.Forms, должны хорошо знать, что, для изменения состояния какого либо контрола из потока его — контрол — не создававшего , обязательно должно проверяться свойство контрола InvokeRequired. Код ниже, который может смутить новичков, несомненно давно уже отложился в памяти программистов неоднократно имевших дело с потоками:

Представим, что на форме есть Label, текст в котором должен периодически обновляться из другого потока. Так вот примерно следующим образом будет выглядеть функция для обновления:

delegate void UpdateLabelDelegate(string msg);

public void displayMessage(string Msg)
        {
            if (msgResceipient != null)
            {
                if (!msgResceipient.InvokeRequired)
                {
                   msgResceipient.Text = Msg;
                }
                else
                {
                    UpdateLabelDelegate d = new UpdateLabelDelegate(displayMessage);
                    this.Invoke(d, new object[] { msgResceipient, Msg });
                }
            }
        }

Но вот для WPF приложений такой код не подойдет. В принципе сама конструкция остается практически без изменений, но используемые методы изменяются примерно следующим образом:

delegate void UpdateLabelDelegate(string msg);

public void displayMessage(string Msg)
        {
            if (msgResceipient != null)
            {
                if (msgResceipient.Dispatcher.CheckAccess())
                {
                   msgResceipient.Content= Msg ;
                }
                else
                {
                showMessageDelegate d = new showMessageDelegate(displayMessage);
                msgResceipient.Dispatcher.BeginInvoke(d,
                    new object[] { msgResceipient, Msg });
                }
            }
        }

Кстати, можете не искать Dispatcher.CheckAccess() в IntelliSense — его там нет. Разработчики по непонятным причинам не стали его туда включать… Тем не менее компилятор при использовании этого метода ругаться не будет.

Надеюсь кому то эта информация поможет.
Извините, если баян, но когда мне это было нужно, я так и не смог найти в рунете ответ 😉

Кстати, если вам известна более хорошая техника многопоточного программирования для WPF, а тем более, если есть хороший пример того как увязать databinding с многопоточностью, буду рад увидеть ссылки (надеюсь спам бот их не порежет) 🙂

2 комментария on "Замена InvokeRequired в WPF"


  1. delegate void ActionHandler();
    void post(ActionHandler action) {
      if (this.InvokeRequired) this.BeginInvoke(action); else action();
      // if (this.Dispatcher.CheckAccess()) action(); else this.Dispatcher.BeginInvoke(action);
    }
    ...
    public void selLabel(string text) {
      post(()=>{ myLabel.Text=text; });
    }
    
    Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.