1

私はTPLの芸術を学んでいます。そのため、TPL から段階的に UI を更新しようとしましたが、うまくいきません。私が使用しているコードは次のとおりです。

    int i = 0, flag = 5;
    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.StartNew(() =>
    {
        while (i < flag)
        {
            Task.Factory.StartNew(() =>
            {
                this.Text = i.ToString();
                //System.Threading.Thread.SpinWait(50000000);
            }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
            i++;
            System.Threading.Thread.Sleep(1000);

        }
    }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);

Windows タイトル バーの UI を段階的に更新しようとしています。コードは例外なく実行されますが、i の値が 5 になるまで UI は更新されません。1、次に 2 というように、i が 5 になるまで続きます。

プログラムを実行しているときに、タスクが完了するか終了するまでプログラムがハングすることに気付きました。

タスクの使用時に UI を更新することに関して、何が間違っていますか?

別のアプローチ 1

        Task.Factory.StartNew(() =>
        {
            Parallel.For(1, 6, i =>
            {
                System.Threading.Thread.SpinWait(500000000);  do work here   
                BeginInvoke((Action)delegate { this.Text = i.ToString(); });
            });
        });  

別のアプローチ 2

int i = 0, flag = 5;
            var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
            Task.Factory.StartNew(() =>
            {
                while (i < flag)
                {
                    Task.Factory.StartNew(() =>
                    {
                        this.Text = i.ToString();
                    }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
                    i++;
                    System.Threading.Thread.SpinWait(50000000); // do work here   


                }
            }); // <---- Removed arguments (specifically uiScheduler)
4

1 に答える 1

4

最初のタスクを開始するときに uiScheduler コンテキストを使用するようにタスクに指示しています。それを削除すると、コードは問題ないはずです。

int i = 0, flag = 5;
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
    while (i < flag)
    {
        Task.Factory.StartNew(() =>
        {
            this.Text = i.ToString();
        }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
        i++;
        System.Threading.Thread.Sleep(1000);

    }
}); // <---- Removed arguments (specifically uiScheduler)
于 2013-06-05T12:24:39.910 に答える