.Net并行编程(5).NET中的异步编程Async与Await
序言
.net中实现异步有两种方式,第一种是多线程的方式,第二种是使用异步函数,其实在异步函数中使用的还是多线程的技术。
.net在System.Threading和System.Threading.Tasks这两个命名空间中提供了Thread,ThreadPool,和Task三个类来处理多线程的问题,
其中Thread是建立一个专用线程,ThreadPool是使用线程池中工作线程,而Task类是采用任务的方式,其内部也是使用线程池中的工作线程。
await并非等待
async
异步调用前后可能运行在不同的线程
异步不等于多线程
yield
1.同步
private void button1_Click(object sender, EventArgs e) { this.label1.Text = DoWork(); } private string DoWork() { Thread.Sleep(5000); return "StartDo"; }
2.异步(有返回值)
private async void button2_Click(object sender, EventArgs e) { this.label1.Text = await DoWorkAsync(); } private Task<string> DoWorkAsync() { return Task.Run(() => { Thread.Sleep(5000); return "StartDo"; }); }
3.异步(无返回值)
private async void button3_Click(object sender, EventArgs e) { await Task.Run(() => { Thread.Sleep(3000); MessageBox.Show("StartDo"); }); }
4.具有多个await的异步方法
private async void button4_Click(object sender, EventArgs e) { await Task.Run(() =>{ Thread.Sleep(3000);}); MessageBox.Show("1"); await Task.Run(() => { Thread.Sleep(3000); }); MessageBox.Show("2"); await Task.Run(() => { Thread.Sleep(3000); }); MessageBox.Show("3"); }
异步任务如何取消
取消令牌CancellationTokenSource
async Task底层
https://sharplab.io/
using System; using System.Threading; using System.Threading.Tasks; public class C { public void M() { } public async Task Foo() { await Task.Delay(3000); } }
底层使用了状态机
using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.DisableOptimizations)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] public class C { [CompilerGenerated] private sealed class <Foo>d__1 : IAsyncStateMachine { public int <>1__state; public AsyncTaskMethodBuilder <>t__builder; public C <>4__this; private TaskAwaiter <>u__1; private void MoveNext() { int num = <>1__state; try { TaskAwaiter awaiter; if (num != 0) { awaiter = Task.Delay(3000).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <Foo>d__1 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } } else { awaiter = <>u__1; <>u__1 = default(TaskAwaiter); num = (<>1__state = -1); } awaiter.GetResult(); } catch (Exception exception) { <>1__state = -2; <>t__builder.SetException(exception); return; } <>1__state = -2; <>t__builder.SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine([Nullable(1)] IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine([Nullable(1)] IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } public void M() { } [NullableContext(1)] [AsyncStateMachine(typeof(<Foo>d__1))] [DebuggerStepThrough] public Task Foo() { <Foo>d__1 stateMachine = new <Foo>d__1(); stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } }
同步上下文
1.使用Synchronization同步上下文切换UI线程
2.TaskScheduler
常见误区
资料
https://www.bilibili.com/video/BV1yB4y1R7tc/?spm_id_from=333.788&vd_source=a56db24cb8cab4dd8153f9a519787c89
https://github.com/BYJRK/DotNet-Discussions/discussions/154
https://www.cnblogs.com/Vincent-yuan/p/13417356.html
https://www.cnblogs.com/shanzhiming/p/12439214.html
http://www.cnblogs.com/x-xk/archive/2013/06/05/3118005.html
http://www.cnblogs.com/tdws/p/5679001.html
http://www.cnblogs.com/liqingwen/p/5831951.html
http://www.cnblogs.com/liqingwen/p/5831951.html