C# Task(任务调度)
参考:https://www.cnblogs.com/zhaoshujie/p/11082753.html
一个Task表示一个异步操作,Task的创建和执行都是独立的,因此可以对关联操作的执行拥有完全的控制权。
一:Task的优势
1: Task支持线程的取消、完成、失败通知等交互性操作
2: Task支持线程执行的先后次序
1 2 3 4 5 6 7 8 9 | Task t = new Task(() => { }); t.ContinueWith((task) => { }); t.Start(); |
二:Task的完成状态
任务Task有这样一些属性,让我们查询任务完成时的状态:
1: IsCanceled,因为被取消而完成
2: IsCompleted,成功完成
3: IsFaulted,因为发生异常而完成
1 2 3 4 5 6 7 | CancellationTokenSource cts = new CancellationTokenSource(); Task< int > t = new Task< int >(() => Add(cts.Token), cts.Token); t.Start(); t.ContinueWith(TaskEnded); //等待按下任意一个键取消任务 Console.ReadKey(); cts.Cancel(); |
任务Task创建方式
方式一、new Task 无返回值
1 2 | Task task = new Task(() =>{}); task.Start(); |
new Task 有返回值的方式,Task 与 ContinueWith
1 2 3 4 5 6 7 8 9 10 | //先执行Task Task< int > task = new Task< int >(() => { return 0; }); //其次执行ContinueWith task.ContinueWith(t => { int result = t.Result; }); task.Start(); |
方式二、使用 TaskMethod 无返回值
1 2 | Task task = new Task(() => TaskMethod( "Task 2" )); task.Start(); |
方式三、Task.Run
1 | Task task = Task.Run(() => TaskMethod( "Task 3" )); |
方式四、直接异步的方法
1 | Task.Factory.StartNew(() => TaskMethod( "Task 3" )); |
方式五、异步
1 2 3 4 5 6 7 | Task.Run(async () => { await Task.Factory.StartNew(() => { }); }); |
Task任务并行
1 2 3 4 5 6 7 8 9 10 11 12 13 | List<Task> taskList = new List<Task>(); taskList.Add(Task.Run(() => { })); taskList.Add(Task.Run(() => { })); taskList.Add(Task.Run(() => { })); |
//主线程阻塞,等待结束
Task.WaitAll(taskList.ToArray());
主线程 Code ....执行
方式三、异步非阻塞
1 2 3 4 5 6 7 8 9 10 11 | Task[] tlist = new Task[] { Task.Factory.StartNew(() => { Thread.Sleep(3000); }), Task.Factory.StartNew(() => { Thread.Sleep(90000); }) }; Task.WhenAny(tlist).ContinueWith((s) => { return s; }); |
使用IProgress实现异步编程的进程通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | private void btnSub_Click( object sender, RoutedEventArgs e) { Task task = Display(); } void DoProcessing(IProgress< int > progress) { if (progress != null ) { progress.Report(1); } } async Task Display() { //当前线程 var progress = new Progress< int >(percent => { this .Title = percent.ToString(); }); //线程池线程 await Task.Run(() => DoProcessing(progress)); } |
本文来源参考:https://www.cnblogs.com/zhaoshujie/p/11082753.html
什么是并行
并行是指两个或者多个事件在同一时刻发生
在程序运行中,并行指多个CPU核心同时执行不同的任务;对于单核心CPU,严格来说是没有程序并行的。并行是为了提高任务执行效率,更快的获取结果。
与并发的区别
并发是指两个或者多个事件在同一时段发生。
相对于并行,并发强调的是同一时段,是宏观上的同时发生。实际上,同一时刻只有一个任务在被执行,多个任务是分时地交替执行的。并发是为了更合理地分配资源。
实现并行,我们要借助进程和线程。
进程是正在运行的程序的实例。
线程被包含在进程之中,是进程中的实际运作单位。
前台线程和后台线程
.NET把线程分为前台线程和后台线程,两者几乎相同,唯一的区别是,前台线程会阻止进程的正常退出,后台线程则不会。
线程池 ThreadPool
线程的创建和销毁要耗费很多时间,而且过多的线程不仅会浪费内存空间,还会导致线程上下文切换频繁,影响程序性能。为改善这些问题,.NET运行时(CLR)会为每个进程开辟一个全局唯一的线程池来管理其线程。
多线程
1、在执行一个较长时间的任务时,不能阻塞UI界面响应,必须通过后台线程处理;
2、在执行批量计算密集型任务时,采用多线程技术可以提高运行效率;
传统使用的多线程技术有:
Thread & ThreadPool
Timer
BackgroundWorker
Task内部也是对ThreadPool的封装
采用并行编程方法:
Parallel.For(1, 10000, x=>
{
bool b = IsPrimeNumber(x);
Console.WriteLine($"{i}:{b}");
});
//使用并行循环处理数据更新
List<string> lists = new List<string>();
System.Threading.Tasks.Parallel.For(0, lists.Count, (int i) =>
{
string sql = string.Format("update table1 set IsExit =1 where Id='{0}'", lists[i]);
Execute(sql);
});
和Task类似,Parallel类仍然是对ThreadPool的封装。
需要通知一个任务结束,或一个任务等待某个条件进入下一个状态,这就需要用到任务同步的技术。
采用WaitOne来等待
异步编程模型(await、async)
非UI线程不能访问UI控件,可以使用Invoke
多线程环境下的数据安全
private static ConcurrentDictionary<int, string> Dic = new ConcurrentDictionary<int, string>();
//添加操作
Dic.TryAdd(i, i.ToString());
多线程的异常处理
基本原则:不要轻易捕获根异常;
多线程的内部异常不会传播到主线程,应该在内部进行处理,可以通过事件推到主线程来;
应用程序层面可以捕获根异常,做一些记录工作,切不可隐匿异常。
将异常包装成事件推送到主线程,交给主线程处理。
参考:https://www.cnblogs.com/seabluescn/p/12973936.html
异步编程中,线程之间只要互不影响,考虑同步问题即可。而在并行编程中,则要求多个线程在同一时刻同时运行。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂