网站的布局结构顺企网下载
网站的布局结构,顺企网下载,wordpress做导航页面模板,wordpress安装文件是哪个异步编程是一种思路异步相当于对线程池的封装await相当于让另一个线程来干这个事 常见概念已经有多线程了#xff0c;为何还要异步多线程与异步是不同的概念多线程与异步的适用场景不同*多线程**异步* 什么是异步任务(Task)包含了异步任务的各种状态的一个引用类型对于异步任务…异步编程是一种思路异步相当于对线程池的封装await相当于让另一个线程来干这个事 常见概念已经有多线程了为何还要异步多线程与异步是不同的概念多线程与异步的适用场景不同*多线程**异步* 什么是异步任务(Task)包含了异步任务的各种状态的一个引用类型对于异步任务的抽象任务的结果 异步方法(async Task)*async Task* 重要思想:不阻塞!*常见阻塞情形* 同步上下文*ConfigureAwait(false)* 一发即忘Fire-and-forget 简单任务如何创建异步任务Task.Run()Task.Factory.StartNew()new Task Task.Start()例子 如何同时开启多个异步任务任务如何取消任务超时如何实现在异步任务中汇报进度如何在同步方法中调用异步方法 常见的误区异步一定是多线程异步方法一定要写成async Taskawait一定会切换同步上下文异步可以全面取代多线程Task.Result 一定会阻塞当前线程开启的异步任务一定不会阻塞当前线程 同步机制传统方法轻量型并发集合第三方库 常见概念
已经有多线程了为何还要异步
多线程与异步是不同的概念
异步并不意味着多线程单线程同样可以异步 异步默认借助线程池 多线程经常阻塞而异步要求不阻塞
多线程与异步的适用场景不同
多线程
适合CPU密集型操作
适合长期运行的任务
线程的创建与销毁开销较大
提供更底层的控制操作线程、锁、信号量等
线程不易于传参及返回
线程的代码书写较为繁琐异步
适合IO密集型操作
适合短暂的小任务
避免线程阻塞提高系统响应能力什么是异步任务(Task)
包含了异步任务的各种状态的一个引用类型
正在运行、完成、结果、报错等
public class TODO {public static event Funcobject, string foo;static void Main() {Taskstring task new Taskstring((n) {Thread.Sleep(1500);for (int i 0; i (int)n; i) {Console.WriteLine(DONE {0}, i);}return ok;}, 3);Console.WriteLine(task.Status);task.Start();Console.WriteLine(task.Status);Thread.Sleep(1000);Console.WriteLine(task.Status);Thread.Sleep(2000);Console.WriteLine(task.Status);Console.WriteLine(task.Result);}
}
输出结果
Created
WaitingToRun
Running
DONE 0
DONE 1
DONE 2
RanToCompletion
ok另有ValueTask值类型版本对于异步任务的抽象
开启异步任务后当前线程并不会阻塞而是可以去做其他事情
异步任务(默认)会借助线程池在其他线程上运行
获取结果后回到之前的状态任务的结果
返回值为Task的方法表示异步任务没有返回值
返回值为TaskT则表示有类型为T的返回值异步方法(async Task)
将方法标记async 后可以在方法中使用await关键字
await关键字会等待异步任务的结束并获得结果
async await 会将方法包装成状态机await类似于检查点
MoveNext方法会被底层调用从而切换状态async Task
返回值依旧是Task类型但是在其中可以使用await关键字
在其中写返回值可以直接写TaskT 中的T类型不用包装成TaskTasync void
同样是状态机但缺少记录状态的Task对象
无法聚合异常(Aggregate Exception)需要谨慎处理异常
几乎只用于对于事件的注册*异步编程具有传染性(Contagious) * 一处async处处async 几乎所有自带方法都提供了异步的版本 重要思想:不阻塞!
await会暂时释放当前线程使得该线程可以执行其他工作而不必阻塞线程直到异步操作完成
不要在异步方法里用任何方式阻塞当前线程
常见阻塞情形
Task.Wait() Task.Result
如果任务没有完成则会阻塞当前线程容易导致死锁Task.GetAwaiter().GetResult()不会将Exception 包装为AggregateExceptionTask.Delay() vs. Thread.Sleep()
后者会阻塞当前的线程这与异步编程的理念不符
前者是一个异步任务会立刻释放当前的线程IO等操作的同步方法
其他繁重且耗时的任务 同步上下文
一种管理和协调线程的机制允许开发者将代码的执行切换到特定的线程
WinForms与WPF拥有同步上下文(UI 线程)而控制台程序默认没有
ConfigureAwait(false)
配置任务通过await方法结束后是否会到原来的线程默认为true
一般只有UI线程会采用这种策略TaskScheduler
控制Task的调度方式和运行线程
线程池线程Default
当前线程CurrentThread
单线程。上下文STAThread
长时间运行线程LongRunning优先级、上下文、执行状态等 一发即忘Fire-and-forget
调用一一个异步方法但是并不使用await或阻塞的方式去等待它的结束 无法观察任务的状态(是否完成、是否报错等) 简单任务
如何创建异步任务
Task.Run()
Task.Factory.StartNew()
提供更多功能比如TaskCreationOptions.L ongRunning
Task.Run相当于简化版new Task Task.Start()
很少有创建一个Task却没有让他立刻开始的例子
public class TODO {static async Task Main() {Console.WriteLine(12);Console.WriteLine(ThreadId Environment.CurrentManagedThreadId.ToString());var task await Task.Run(heavyJob);//Console.WriteLine(task);Console.WriteLine(123);}public static int heavyJob() {Console.WriteLine(ThreadId Environment.CurrentManagedThreadId.ToString());Thread.Sleep(10);return 1;}} 如何同时开启多个异步任务
public class TODO {static async Task Main() {var inputs Enumerable.Range(10, 10).ToArray();var tasks new ListTaskint();Console.WriteLine(Environment.CurrentManagedThreadId);foreach (var input in inputs) {tasks.Add(foo(input));}await Task.WhenAll(tasks);var outputs tasks.Select(x x.Result).ToArray();foreach (var output in outputs) {Console.WriteLine(output);}}public static async Taskint foo(int input) {await Task.Delay(5000);return input * 2;}
}任务如何取消
CancellationTokenSource CancellationToken
public class TODO {static async Task Main() {var cts new CancellationTokenSource();try {var task Task.Delay(100000, cts.Token);Thread.Sleep(2000);cts.Cancel();//抛出异常await task;} catch (TaskCanceledException) {Console.WriteLine(ss);} finally {cts.Cancel();}}
}
OperationCanceledException TaskCanceledException
推荐异步方法都带上CancellationToken这一传参
你自己写了异步方法却不支持传入这个————我可以不用但不能没有任务超时如何实现 在异步任务中汇报进度 如何在同步方法中调用异步方法 常见的误区
异步一定是多线程
异步编程不必需要多线程来实现
比如可以在单个线程上使用异步I/O 或事件驱动的编程模型(EAP)
单线程异步:自己定好计时器到时间之前先去做别的事情 多线程异步:将任务交给不同的线程并由自己来进行指挥调度 异步方法一定要写成async Task
async关键字只是用来配合await 使用从而将方法包装为状态机
本质上仍然是Task,只不过提供了语法糖并且函数体中可以直接return Task的泛型类型
接口中无法声明async Task await一定会切换同步上下文
在使用await关键字调用并等待一个异步任务时异步方法不一定会立刻来到新的线程上
如果await了一个已经完成的任务(包括Task.Delay(0))会直接获得结果 异步可以全面取代多线程
异步编程与多线程有一定关系但两者并不是可以完全互相替代 Task.Result 一定会阻塞当前线程
如果任务已经完成那么Task.Result 可以直接得到结果 开启的异步任务一定不会阻塞当前线程
await关键字不一定会立刻释放当前线程所以如果调用的异步方法中存在阻塞(如Thread.Sleep(O)) 那么依旧会阻塞当前上下文对应的线程 同步机制
传统方法
Monitor(lock) Mutex Semaphore EventWaitHandle
轻量型
所有只有SemaphoreSlim不阻塞 ManualResetEventSlim
并发集合
第三方库
AsyncManulResetEvent
Miccrosoft.VisualStudio.ThreadingAsyncLock
Nito.AsyncEx
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/86724.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!