C#多线程之线程基础篇( 六 )

接口另外BackgroundWorker使用了线程池,意味着绝不应该在BackgroundWorker线程上调用Abort
void 工作进度报告(){worker = new BackgroundWorker();worker.WorkerReportsProgress = true;// 支持进度报告worker.WorkerSupportsCancellation = true;// 支持取消worker.DoWork += DoWoker;worker.ProgressChanged += (_, args) => _testOutputHelper.WriteLine($"当前进度:{args.ProgressPercentage}%");worker.RunWorkerCompleted += (sender, args) =>{if (args.Cancelled) _testOutputHelper.WriteLine("工作线程已被取消");else if (args.Error != null) _testOutputHelper.WriteLine("工作线程发生异常: " + args.Error);else _testOutputHelper.WriteLine("任务完成,结果: " + args.Result); // Result来自DoWork};worker.RunWorkerAsync();}private void DoWoker(object? sender, DoWorkEventArgs e){for (int i = 0; i < 100; i+= 10){if (worker.CancellationPending){e.Cancel = true;return;}worker.ReportProgress(i);// 上报进度Thread.Sleep(1000);// 模拟耗时任务}e.Result = int.MaxValue;// 这个值会回传给RunWorkerCompleted}基于任务的异步模式 (TAP)从 .NET Framework 4 开始引入
五、拓展知识小林coding:https://xiaolincoding.com/os/4_process/process_base.html#进程的控制结构
线程优先级线程的Priority属性决定了相对于操作系统中的其它活动线程,它可以获得多少CPU 时间片(time slice) 。
优先级依次递增,在提升线程优先级前请三思,这可能会导致其它线程的 资源饥饿(resource starvation)
enum ThreadPriority { Lowest, BelowNormal, Normal, AboveNormal, Highest }提升线程的优先级并不等于直接优先,因为线程还受进程优先级影响,因此还需要使用System.Diagnostics中的Process类
using (Process p = Process.GetCurrentProcess()){p.PriorityClass = ProcessPriorityClass.High;}ProcessPriorityClass.High是一个略低于最高优先级Realtime的级别 。将一个进程的优先级设置为Realtime是通知操作系统,我们绝不希望该进程将 CPU 时间出让给其它进程 。如果你的程序误入一个死循环,会发现甚至是操作系统也被锁住了,就只好去按电源按钮了o(>_<)o 正是由于这一原因,High 通常是实时程序的最好选择 。
什么是进程退出?进程退出一般出现在以下几种情况:

  • 正常退出,进程执行完任务 。
  • 错误退出,进程遇到不可继续运行的错误(发生异常未捕获导致程序退出)
  • 被操作系统终止,进程本身有问题,比如进程企图访问不属于自己的内存地址
  • 被其它进程终止,比如通过资源管理器我们可以选择终止掉某个进程
以上只有前两种情况是进程自愿退出的,因此,总体上可以分为三类:进程自愿退出,操作系统终止进程以及进程终止进程 。
main()执行结束时会自动隐式调用exit(),windows下叫ExitProcess 。中止整个程序的执行,把控制返还给操作系统,并返回一个整数值,通常0表示正常终止,非0表示异常终止,这个值将会返回给操作系统 。
windows中通过任务管理器,linux中通过kill去杀掉一个进程,其资源是否会释放?会 。进程的特征之一就是动态性,其生存周期就是产生到消亡 。当发生进程终止后,调用进程终止原语,从PCB总线中将其删除,将PCB结构归还给系统,释放该进程的资源给其父进程或者操作系统 。
但不完全会 。如果用户强行终止了.NET 进程,所有线程都会被当作后台线程一般丢弃,有的资源没来得及释放,需要等待一段时间
Process类有以下两种方法: