WPFのプログレスバーprogressbar,実行時間elapse timeと待機spinnerの実装

5216 ワード

今日使います.NET 4.5におけるTPLの特性を小例として,WPFのプログレスバー,ランタイムelapse time,および待機spinnerを実現した.
まず図を描きましょう.
 
この例は、同期バージョン(Sync)、非同期バージョン(Async)、同時バージョン(Parallel)、およびデータバインディングによって実現される同時バージョン(Parallel with Data Binding)の4つのインプリメンテーションを含む.コードはGithubに置かれています.ここでSpinnerの実装はstackoverflow上のDrew Noakesが提供するコード#コード#に由来する.

1.同期バージョン(Sync)


このバージョンでは、進捗バー、実行時間が更新されず、ユーザーはすべての作業がUIスレッドで行われているため、UI全体がブロックされているため、キャンセルできません.サンプルコードは次のとおりです.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
        internal override void Start()
        {
            startWaiting();
            for (int i = 1; i <= Job.JobNumber; i++)
            {
                Job.TimeConsumingJob();
                m_FinishedJob++;
                m_Progressbar.Value = m_FinishedJob;
            }
            stopWaiting();
        }

2.非同期バージョン(Async)


C#のawait async , 、 , , UI 。 :
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
        internal override async void Start()
        {
            startWaiting();

            try
            {
                for (int i = 1; i <= Job.JobNumber; i++)
                {
                    await Task.Factory.StartNew(Job.TimeConsumingJob, m_CancellationTokenSource.Token);
                    m_FinishedJob++;
                    m_Progressbar.Value = m_FinishedJob;
                }
            }
            catch (OperationCanceledException)
            {
                m_CancellationTokenSource = new CancellationTokenSource();
            }
            
            stopWaiting();
        }

3. バージョン(Parallel)

, UI 。 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        internal override async void Start()
        {
            startWaiting();

            List<Task> taskList = new List<Task>();
            for (int i = 1; i <= Job.JobNumber; i++)
            {
                taskList.Add(
                        Task.Factory.StartNew(Job.TimeConsumingJob).ContinueWith(t =>
                            {
                                m_FinishedJob++;
                                m_Progressbar.Value = m_FinishedJob;
                            },
                        m_CancellationTokenSource.Token,
                        TaskContinuationOptions.None,
                        TaskScheduler.FromCurrentSynchronizationContext())
                        );
            }

            try
            {
                await Task.WhenAll(taskList);
            }
            catch (OperationCanceledException)
            {
                m_CancellationTokenSource = new CancellationTokenSource();
            }

            stopWaiting();
        }

4.データバインディングによる バージョン(Parallel with Data Binding)

, Data Binding, UI 。