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 への呼び出しを最小限に抑え、ProgressChanged および RunWorkerComplete イベントによるバックグラウンド スレッドと UI スレッド間の自動同期をサポートする BackgroundWorker の使用も試してください。

于 2013-01-16T15:15:41.580 に答える
0

WPF DispatcherのタスクキューがDispatcherOperationあるため、呼び出すtk.Wait();と、終了するまでDispatcherスレッドをブロックしますtk。この待機を一時停止して再開することはできませんが、キャンセルするだけDispatcherOperationです。しかし、あなたの場合、ボタン(またはウィンドウ全体)を無効にして、tk終了時に有効にする方がよいと思います。したがって、非同期で完了するのを待つことを検討する必要がありますtk

于 2013-01-16T13:36:51.447 に答える