How to update a WPF Control from the TPL Task?
How to update a WPF Control from the TPL Task?
Fine so I tried some scenarios to use Dispatcher but anyway it gives the error. I need help guys!
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Application.Current.Dispatcher.Invoke((Action)MyInit);
backgroundDBTask = Task.Factory.StartNew(() =>
{
DoSomething1();
}, TaskCreationOptions.LongRunning);
开发者_JAVA技巧 backgroundDBTask.ContinueWith((t) =>
{
// ... UI update work here ...
},
TaskScheduler.FromCurrentSynchronizationContext());
}
void DoSomething1()
{
// MyInit();
int number = 0;
while (true)
{
if (state)
{
Thread.Sleep(1000);
Console.WriteLine("Begin second task... {0}", number++);
// mostCommonWords = GetMostCommonWords(words) + string.Format(" Begin second task... {0}", number++);
textBox2.Text = (number++).ToString(); // Gives the error
Dispatcher.BeginInvoke(); // How it should be ?
}
}
}
Thank you!
You need to pass a delegate that does your work to BeginInvoke
.
BeginInvoke
will asynchronously run this delegate on the UI thread.
For example:
Dispatcher.BeginInvoke(new Action(delegate {
textBox2.Text = number.ToString();
}));
I know there is already an answer here and what Slaks gave you will fix it since it will use the Dispatcher thread thus will not throw an exception for accessing a control from a different thread
.
But, I notice this.
backgroundDBTask = Task.Factory.StartNew(() =>
{
DoSomething1();
}, TaskCreationOptions.LongRunning);
With this
backgroundDBTask.ContinueWith((t) =>
{
// ... UI update work here ...
},
TaskScheduler.FromCurrentSynchronizationContext());
You already have a comment where to update the UI and you also gave it the SynchronizationContext
. Why are you still trying to update the UI
inside of your DoSomething1
?
Unless your purpose of your Task
is to update the UI
then there is no need to use the ContinueWith
. Instead just pass the SynchronizationContext
and it should work without having to explicitly call the Dispatcher.BeginInvoke
.
backgroundDBTask = Task.Factory.StartNew(() =>
{
DoSomething1();
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
精彩评论