InvokeRequired в wpf
Я использовал эту функцию в приложении Windows forms
:
delegate void ParametrizedMethodInvoker5(int arg);
private void log_left_accs(int arg)
{
if (InvokeRequired)
{
Invoke(new ParametrizedMethodInvoker5(log_left_accs), arg);
return;
}
label2.Text = arg.ToString();
}
Но в WPF
он не работает. Почему?
Ответы
Ответ 1
В WPF метод Invoke
находится в диспетчере, поэтому вам нужно вызвать Dispatcher.Invoke
вместо Invoke
. Кроме того, нет свойства InvokeRequired
, но диспетчер имеет метод CheckAccess
(по какой-то причине он скрыт в intellisense). Поэтому ваш код должен быть:
delegate void ParametrizedMethodInvoker5(int arg);
void log_left_accs(int arg)
{
if (!Dispatcher.CheckAccess()) // CheckAccess returns true if you're on the dispatcher thread
{
Dispatcher.Invoke(new ParametrizedMethodInvoker5(log_left_accs), arg);
return;
}
label2.Text= arg.ToString();
}
Ответ 2
В WPF используйте метод CheckAccess
вместо InvokeRequired
if (!CheckAccess()) {
// On a different thread
Dispatcher.Invoke(() => log_left_accs(arg));
return;
}
Ответ 3
проверить Dispatcher.CheckAccess()
Ответ 4
WPF использует Dispatcher
для управления доступом к насосу сообщений, а не для того, чтобы каждый элемент управления отвечал за доступ к потоку пользовательского интерфейса.
Вы должны использовать Dispatcher.Invoke
для добавления делегата в поток пользовательского интерфейса в приложении WPF.
Также стоит отметить, что InvokeRequired
действительно не требуется в приложении winform, и это не то, что вы должны проверять в приложении WPF. Вы должны знать, что вы не находитесь в потоке пользовательского интерфейса при вызове Invoke
. Вы никогда не должны находиться в ситуации, когда данный метод иногда вызывается из потока пользовательского интерфейса и иногда вызывается из фонового потока. Выбери один; либо всегда заставляют вызывающего абонента ссылаться на поток пользовательского интерфейса перед вызовом заданного метода (поэтому вам не нужно вызывать) или предположить, что вызывающий объект не будет в потоке пользовательского интерфейса при вызове метода. Также стоит отметить, что вызов Invoke
, когда вы уже находитесь в потоке пользовательского интерфейса, отлично. Нет ошибок или проблем, которые могут возникнуть из-за случайного экземпляра повторного вызова потока пользовательского интерфейса (там очень низкая стоимость исполнения, поэтому просто не добавляйте ненужный код для него повсюду).