接着上一篇:一個利用 Parallel.For 並行處理任務,帶有進度條(ProgressBar)的 WinForm 實例(上)html
直接貼代碼了:oop
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(); } } }
運行截圖:this
謝謝瀏覽!spa
原文出處:https://www.cnblogs.com/Music/p/a-winform-instance-with-progressbar-for-parallel-processing-tasks-using-parallel-for.html3d