开发者

How to update a WPF Control from the TPL Task?

开发者 https://www.devze.com 2023-04-12 00:40 出处:网络
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!

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()); 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号