UPDATE
Se si sta utilizzando C# 5 e .NET 4.5 o superiore è possibile evitare di ottenere su un altro thread, in primo luogo con async
e await
, ad esempio:
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;
}
Facile:
Dispatcher.BeginInvoke(new Action(delegate()
{
myListBox.Items.Add("new item"));
}));
Se sei in code-behind. In caso contrario, è possibile accedere al Dispatcher (che è su ogni UIElement
) utilizzando:
Application.Current.MainWindow.Dispatcher.BeginInvoke(...
Ok thats un sacco in una sola riga lasciarmi andare su di esso:
Quando si desidera aggiornare un controllo dell'interfaccia utente voi, come il messaggio dice, devono farlo dal thread dell'interfaccia utente. C'è un modo integrato per passare un delegato (un metodo) al thread dell'interfaccia utente: lo Dispatcher
. Una volta ottenuto il numero Dispatcher
, è possibile inviare Invoke()
di BeginInvoke()
passando a un delegato da eseguire sul thread dell'interfaccia utente. L'unica differenza è Invoke()
restituita solo dopo che il delegato è stato eseguito (ad es.nel tuo caso è stato aggiunto il nuovo elemento del ListBox) mentre BeginInvoke()
verrà restituito immediatamente, quindi l'altro thread da cui stai chiamando può continuare (il Dispatcher eseguirà presto il tuo delegato in quanto può essere comunque immediatamente disponibile).
ho passato un delegato anonimo sopra:
delegate() {myListBox.Items.Add("new item");}
Il bit tra il {} è il blocco del metodo. Questo è chiamato anonimo perché solo uno è stato creato e non ha un nome (di solito è possibile farlo usando un'espressione lambda, ma in questo caso C# non può risolvere il metodo BeginInvoke() per chiamare). Oppure avrei potuto un'istanza di un delegato:
Action myDelegate = new Action(UpdateListMethod);
void UpdateListMethod()
{
myListBox.Items.Add("new item");
}
poi passata che:
Dispatcher.Invoke(myDelegate);
ho usato anche la classe di azione, che è una costruito nel delegato ma avrebbe potuto creare il proprio - si può leggere più sui delegati su MSDN in quanto questo sta andando un po 'fuori tema ..
Sono troppo assonnato per scrivere una risposta completa, ma ecco un suggerimento: guardarsi intorno (Google, SO o MSDN) per Dispatcher. Ora vado a letto. –