0

是否可以强制 UI 线程停止等待任务完成,通过 Dispatcher 更新 UI 控件,然后让 UI 恢复到等待任务完成?

我刚刚尝试了以下代码,但它似乎不起作用

UpdatePB(int NewValue) 

方法正在由非 UI 线程执行。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Threading;

namespace UpdateControlViaDispatcherUITaskWaitAll
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void UpdatePB(int NewValue)
        {
            pb1.Value = NewValue;
        }


        private void btn1_Click(object sender, EventArgs e)
        {
            Task tk = Task.Factory.StartNew(() =>
            {
                Worker();
            });
            tk.Wait();
        }

        public void Worker()
        {
            int currentValue = 0;

            for (int i = 0; i < 100; i++)
            {
                currentValue = i;

                Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
                {
                    UpdatePB(currentValue);
                }));


                Thread.Sleep(1000);
            }
        }
    }
}
4

2 回答 2

2

避免阻塞 UI 线程:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Task.Factory
        .StartNew(this.Worker)
        .ContinueWith(this.OnWorkerCompleted);
}

public void Worker()
{
    Dispatcher.Invoke(new Action(() =>
    {
        btn1.IsEnabled = false;
    }));
    // your stuff here...
}

private void OnWorkerCompleted(Task obj)
{
    Dispatcher.Invoke(new Action(() =>
    {
        btn1.IsEnabled = true;
    }));
}

尽量减少对 Dispatcher 的调用,并尝试使用 BackgroundWorker,它支持后台线程和 UI 线程之间的自动同步,带有 ProgressChanged 和 RunWorkerComplete 事件。

于 2013-01-16T15:15:41.580 回答
0

WPF Dispatcher有任务队列DispatcherOperation,所以当你调用tk.Wait();它时会阻塞 Dispatcher 线程直到tk完成。您无法暂停此等待并再次恢复,而只能取消DispatcherOperation。但在你的情况下,我假设你最好禁用按钮(或整个窗口)并在tk完成时启用它。所以你应该考虑异步等待tk完成。

于 2013-01-16T13:36:51.447 回答