代码改变世界

一个利用 Parallel.For 并行处理任务,带有进度条(ProgressBar)的 WinForm 实例(下)

2019-03-25 19:53  音乐让我说  阅读(592)  评论(0编辑  收藏  举报

 

接着上一篇:一个利用 Parallel.For 并行处理任务,带有进度条(ProgressBar)的 WinForm 实例(上)

 

直接贴代码了:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormUI.UIForms
{
    public partial class TaskParallelTestForm : Form
    {
        public TaskParallelTestForm()
        {
            InitializeComponent();
        }

        IEnumerable<int> _data = Enumerable.Range(1, 100);
        Action _cancelWork;

        private void DoWorkItem(
            int[] data,
            int item,
            CancellationToken token,
            Action<int> progressReport,
            ParallelLoopState loopState)
        {
            // observe cancellation
            if (token.IsCancellationRequested)
            {
                loopState.Stop();
                return;
            }

            // simulate a work item
            Thread.Sleep(500);

            // update progress
            progressReport(item);
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            // update the UI
            this.btnStart.Enabled = false;
            this.btnStop.Enabled = true;

            Action enableUI = () =>
            {
                // update the UI
                this.btnStart.Enabled = true;
                this.btnStop.Enabled = false;
                this._cancelWork = null;
            };

            Action<Exception> handleError = (ex) =>
            {
                // error reporting
                MessageBox.Show(ex.Message);
            };

            try
            {
                // prepare to handle cancellation
                var cts = new CancellationTokenSource();
                var token = cts.Token;

                this._cancelWork = () =>
                {
                    this.btnStop.Enabled = false;
                    cts.Cancel();
                };

                var data = _data.ToArray();
                var total = data.Length;

                // prepare the progress updates
                this.progressBar1.Value = 0;
                this.progressBar1.Minimum = 0;
                this.progressBar1.Maximum = total;

                var syncConext = SynchronizationContext.Current;

                Action<int> progressReport = (i) =>
                    syncConext.Post(_ => this.progressBar1.Increment(1), null);

                // offload Parallel.For from the UI thread 
                // as a long-running operation
                var task = Task.Factory.StartNew(() =>
                {
                    Parallel.For(0, total, (item, loopState) =>
                        DoWorkItem(data, item, token, progressReport, loopState));
                    // observe cancellation
                    token.ThrowIfCancellationRequested();
                }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

                task.ContinueWith(_ =>
                {
                    try
                    {
                        task.Wait(); // rethrow any error
                    }
                    catch (Exception ex)
                    {
                        while (ex is AggregateException && ex.InnerException != null)
                            ex = ex.InnerException;
                        handleError(ex);
                    }
                    enableUI();
                }, TaskScheduler.FromCurrentSynchronizationContext());
            }
            catch (Exception ex)
            {
                handleError(ex);
                enableUI();
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            if (this._cancelWork != null)
                this._cancelWork();
        }
    }
}

 

运行截图:

谢谢浏览!