版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38801354/article/details/79788601
1 BackgroundWorker
类
aysnc/await
特性适合那些需要在后台完成的不相关的小任务,但有时候,可能需要另建一个线程,在后台持续运行以完成某项工作,并时不时地与主线程进行通信。而 BackgroundWorker
类就是为此而生。
BackgroundWorker
类有几个主要的成员:
- 属性:
WorkerReportProgress
:布尔值,可写可读,用于表示是否支持向主线程汇报它的进度;WorkerSupportsCancellation
:布尔值,可写可读,用于表示是否支持从主线程取消;IsBusy
:只读布尔值,检查后台任务是否在运行;CancellationPending
:只读布尔值,由CancellAsnyc
方法控制,DoWork
事件程序需要检查其属性来决定是否应该停止处理;
- 方法:用于初始化行为或改变状态
RunWorkerAsync()
:调用RunWorkerAsync()
方法可以获取后台线程并执行DoWork
事件处理程序;CancellAsnyc()
:用于改变CancellationPending
属性为true
,DoWork
事件程序必须检查其属性值来决定是否停止处理;ReportProgress()
:向主线程汇报进度,主线程可以处理ProgressChanged
事件上的处理程序;
- 事件:
DoWork
:后台线程开始的时候触发DoWork
事件(创建BackgroundWorker
类必需);ProgressChanged
:在后台任务汇报状态的时候触发ProgressChanged
事件;RunWorkerComplated
:在后台任务结束的时候触发RunWorkerComplated
事件;
事件处理程序都有一个 object
对象的引用作为 第一个参数,以及 EventArgs
类的特定子类作为 第二个参数,对应的 EventArgs
类依次分别是:
DoWorkEventArgs
:
Argument
Result
Cancel
ProgressChangedEventArgs
:
ProgressPercentage
UserState
RunWorkerCompletedEventArgs
:
Cancelled
Error
Result
UserState
示例代码:
using System.Windows;
using System.ComponentModel;
sing System.Threading;
namespace SimpleWorker
{
public partial class MainWindow:Window
{
// 初始化 BackgroundWorker
BackgroundWorker bgWorker = new BackgroundWorker();
public MainWindow()
{
InitializeCompoonent();
// 设置 BackgroundWorker 属性
bgWorker.WorkerReportsProgress = true;
bgWorker.WorkerSupportsCancellation = true;
// 链接BackgroundWorker对象的处理程序
bgWorker.DoWork += DoWork_Handler;
bgWorker.ProgressChanged += ProgressChanged_Handler;
bgWorker.RunWorkerCompleted += RunWorkerCompleted_Handler;
}
private void btnProcess_Click(object sender, RoutedEventArgs e)
{
progressBar.Value = args.ProgressPercentage;
}
private void DoWork_Handler(object sender, DoWorkerEeventArgs args)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i=1; i<=10; i++)
{
if (worker.CancellationPending)
{
args.Cancel = true;
break;
}
else
{
worker.ReportProgress(i*10);
Thread.Sleep(500);
}
}
}
private void RunWorkerCompleted_Handler(object sender, RunWorkerCompletedEventArgs args)
{
progressBar.Value = 0;
if (args.Cancelled)
{
MessageBox.Show("Process was cancelled.", "Process Cancelled");
}
else
{
MessageBox.Show("Process completed normally.", "Process Completed");
}
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
bgWorker.CancelAsync();
}
}
}
2 任务并行库
任务并行库(Task Parellel Library),它是BCL的一个类库,极大简化了并行编程。
2.1 并行循环
Parallel.For
循环和 Parallel.ForEach
循环位于 System.Threading.Tasks
命名空间中,使用它们可以使得彼此独立的迭代程序运行再不同的处理器上 并行 处理。
Parallel.For
循环有 12 个重载,最简单的示例:
using System;
using System.Threading.Tasks;
namespace ExampleParallelFor
{
class Program
{
static void Main()
{
Parallel.For(0, 15, i => {
Console.WriteLine("The square of {0} is {1}", i, i*i); // 此时输出的次序不能保证
})
}
}
}
同理使用 Parallel.ForEach
最简单重载的示例
using System;
using System.Threading.Tasks;
namespace ParallelForeach1
{
static void Main()
{
string[] squares = new string[] {"Hello", "World", "!"};
Parallel.ForEach(squares, i => {
Console.WriteLine(string.Format("{o} has {1} letters", i, i.Length));
})
}
}