0

アプリで Task クラスを使用しています。これは WPF アプリケーションではありません。問題は、次のように、UI スレッドでタスク本体から関数を呼び出す可能性があるかどうかです。

var task = new Task(() => DoSmth(1));
task.Start();

public void DoSmth(int arg)
    {
        //smth
        CallNotifFuncOnUIThread(() => Notify(1));
        //smth ELSE
        CallNotifFuncOnUIThread(() => Notify(2));//notify AGAIN
        //smth ELSE
    }

public void Notify(int arg)
    {
        progressBar1.Value = arg;
    }

それとも、この問題の他の解決策がありますか? BackgroundWorker クラスについては知っていますが、Tasks についてはどうでしょうか。

4

4 に答える 4

1

タスクがある場合は、正しいスケジューラを提供することにより、GUI スレッドで開始できます。

Task.Factory.StartNew(() => DoSomethingOnGUI(), TaskScheduler.FromCurrentSynchronizationContext());
于 2013-03-28T12:28:55.407 に答える
1

DoSth() 内でいつでも他のメソッドを呼び出すことができます

Dispatcher.Invoke(...);
Dispatcher.BeginInvoke(...);

Task.ContinueWith(...)タスクの処理が終了した後にユーザーが sth を実行することもできます...

于 2013-03-28T12:27:02.927 に答える
0

UI は通常 STA です。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms680112(v=vs.85).aspxを参照してください。

したがって、UI で UI スレッド以外から何かを行うには、スレッドにメッセージを何らかの方法で挿入する必要があります。たとえば、htis winform の例を参照してください。

http://weblogs.asp.net/justin_rogers/articles/126345.aspx

使用しているウォーターエバー UI には、同様のシステムが必要になります。

于 2013-03-28T13:06:14.793 に答える
0

WindowsフォームとprogressBar1コンポーネントを使用すると、TPLIProgressインターフェースを使用できますTask

    private void Form1_Load(object sender, EventArgs e)
    {
        Progress<int> progress = new Progress<int>();
        var task = Alg(progress);
        progress.ProgressChanged += (s, i) => { UpdateProgress(i); };
        task.Start();
    }

    public void Notify(int arg)
    {
        progressBar1.Value = arg;
    }

    public static Task Alg(IProgress<int> progress)
    {
        Task t = new Task
        (
            () =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(100);
                    ((IProgress<int>)progress).Report(i);
                }
            }
        );
        return t;
    }
于 2013-03-28T12:45:01.980 に答える