ОБНОВЛЕНИЕ
Если вы используете C # 5 и .NET 4.5 или выше, вы можете избежать перехода на другой поток с помощью async
и await
, например:
private async Task<string> SimLongRunningProcessAsync()
{
await Task.Delay(2000);
return "Success";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
button.Content = "Running...";
var result = await SimLongRunningProcessAsync();
button.Content = result;
}
Легко:
Dispatcher.BeginInvoke(new Action(delegate()
{
myListBox.Items.Add("new item"));
}));
Если вы находитесь в коде позади.В противном случае вы можете получить доступ к Диспетчеру (который есть на каждом UIElement
), используя:
Application.Current.MainWindow.Dispatcher.BeginInvoke(...
Хорошо, это много в одной строке, позвольте мне перейти по нему:
Когда вы хотите обновитьпользовательский интерфейс контролирует, как говорится в сообщении, это нужно сделать из потока пользовательского интерфейса.Существует способ передачи делегата (метода) в поток пользовательского интерфейса: Dispatcher
.Получив Dispatcher
, вы можете либо Invoke()
из BeginInvoke()
передать делегат для запуска в потоке пользовательского интерфейса.Единственная разница в том, что Invoke()
вернется только после запуска делегата (т.е. в вашем случае был добавлен новый элемент ListBox), тогда как BeginInvoke()
вернется немедленно, так что ваш другой поток, из которого вы вызываете, может продолжить (Диспетчеркак можно быстрее запустите ваш делегат, который, вероятно, будет в любом случае незамедлительным.)
Я передал анонимный делегат выше:
delegate() {myListBox.Items.Add("new item");}
Бит между {} является блоком метода.Это называется анонимным, поскольку создается только одно и у него нет имени (обычно это можно сделать с помощью лямбда-выражения, но в этом случае C # не может разрешить вызов метода BeginInvoke ()).Или я мог бы создать экземпляр делегата:
Action myDelegate = new Action(UpdateListMethod);
void UpdateListMethod()
{
myListBox.Items.Add("new item");
}
Затем передать это:
Dispatcher.Invoke(myDelegate);
Я также использовал класс Action, который является встроенным делегатом, но вы могли бы создать свой собственный -Вы можете прочитать больше о делегатах на MSDN, поскольку это немного не по теме ..