WPF的进度条progressbar,运行时间elapse time和等待spinner的实现

今天用.NET 4.5中的TPL的特性做了个小例子,实现了WPF的进度条progressbar,运行时间elapse time和等待spinner。

先上图吧。

这个例子包含4个实现,分别是同步版本(Sync),异步版本(Async),并发版本(Parallel)和通过数据绑定实现的并发版本(Parallel with Data Binding)。代码放在了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#的awaitasync关键字实现异步调用,这样进度条、运行时间都可以更新了,而且用户可以取消,因为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控件。

原文地址:https://www.cnblogs.com/fresky/p/3228471.html