昆明建网站的公司,做策划有帮助的网站,盐山网站制作,亦庄网站设计目录
一#xff0c;引言
二#xff0c;实例演示
2.1 多线程同步执行下载任务#xff0c;任务完成后通知
2.2 异步执行下载任务#xff0c;任务完成后通知
三#xff0c;async/await的用法
3.1 跨线程修改UI控件
3.2 异步获取数据 一#xff0c;引言
首先先来区分…目录
一引言
二实例演示
2.1 多线程同步执行下载任务任务完成后通知
2.2 异步执行下载任务任务完成后通知
三async/await的用法
3.1 跨线程修改UI控件
3.2 异步获取数据 一引言
首先先来区分一下同步方法异步方法和多线程 同步方法调用时需要等待返回结果相当于阻塞了该线程才可以继续往下执行业务异步方法调用时无须等待返回结果等待时释放线程可以继续往下执行业务多线程在主线程之外开启一个新的线程去增加线程同步执行执行业务 关于async/await async和await关键字是C# 5.0时代引入的它是一种异步编程模型它们本身并不创建新线程但可以在自行封装的async中利用Task.Run开启新线程方法体中使用await方法也必须声明为async成对出现如果没有awaitasync关键字也没有意义。 async/await的理解 个人理解await可以看着是代码执行的分裂点当程序执行到await后面的语句时首先系统会将当前的线程释放回归线程池其他程序可调用并捕获当前上下文打上标记进入等待注意期间没有线程阻塞)。当await后语句执行完毕根据标记点调用线程从线程池随机捕获线程有概率是原来的线程执行下面的语句。 二实例演示
2.1 多线程同步执行下载任务任务完成后通知
static void Main(string[] args){DownloadHandle();Console.ReadLine();}public static void DownloadHandle(){Console.WriteLine(下载开始-主线程ID Thread.CurrentThread.ManagedThreadId);var t Download();Task.WaitAll(t);Console.WriteLine(下载完成-主线程ID Thread.CurrentThread.ManagedThreadId);}public static Task Download(){return Task.Run(() {Console.WriteLine(下载线程ID- Thread.CurrentThread.ManagedThreadId);Console.WriteLine(10%);Console.WriteLine(30%);Console.WriteLine(50%);Console.WriteLine(60%);Console.WriteLine(80%);Console.WriteLine(99%);Console.WriteLine(100%);});}
结果输出 可以看的在多线程下载任务时通过Task.WaitAll(t) 等待线程执行完毕后主线程一直处于阻塞状态。
2.2 异步执行下载任务任务完成后通知 static void Main(string[] args){DownloadHandle();Console.ReadLine();}public static async void DownloadHandle(){Console.WriteLine(下载开始-主线程ID Thread.CurrentThread.ManagedThreadId);await Download();Console.WriteLine(下载完成-主线程ID Thread.CurrentThread.ManagedThreadId);}public static Task Download(){return Task.Run(() {Console.WriteLine(下载线程ID- Thread.CurrentThread.ManagedThreadId);Console.WriteLine(10%);Console.WriteLine(30%);Console.WriteLine(50%);Console.WriteLine(60%);Console.WriteLine(80%);Console.WriteLine(99%);Console.WriteLine(100%);});}
可以看的在异步下载任务时主线程未被阻塞。 异步方法async/await的返回值类型一般都是Task或者TaskT类型的当返回值为Task时即方法的返回值类型为void我们可以直接return Task.Run((){})而不必await Task.Run((){})这样也可从一定程度上提高代码执行效率。另外不推荐使用async 修饰void返回值会有异常处理方面的问题。
三async/await的用法 async/await并不能提升代码的执行速度但可以提高响应能力吞吐量即使用异步方式在同一时间可以处理更多的请求。 使用同步方式线程会被耗时操作一直占用直到耗时操作结束使用异步方式程序走到await关键字会立即return释放线程剩下的代码将放到一个回调耗时操作完成时才会回调执行。 因此 对于计算密集型工作使用多线程对于IO密集型工作采用异步机制 从代码整体的架构设计来说由于async/await语法容易使得程序被await传染因此不要从最里面的方法启动线程而是把启动线程的代码放到最外面这样一来绝大部分方法就都不再需要用async修饰了方法就都可以用正常的方式开发了。 3.1 跨线程修改UI控件
通过async/await的机制可以非常简洁轻松的实现跨线程修改UI控件的问题也不用使用Invoke。因为本质上还是在原来的线程上修改的还没有阻塞UI界面
private async void button1_Click(object sender, EventArgs e){var t Task.Run(() {Thread.Sleep(5000);return Hello I am TimeConsumingMethod;});textBox1.Text await t;}
3.2 异步获取数据
在写后端的数据异步处理时通过async/await语法也可轻易实现为了防止async/await语法传染将启动线程的代码放在了最外层这样在Click事件中就可以正常调用了不用在增加async关键字了。 private void button2_Click(object sender, EventArgs e){AsyncFunc();}private async Task AsyncFunc(){DataTable dt await FecthData();this.dataGridView1.DataSource dt;}private async TaskDataTable FecthData(){DataTable dt null;await Task.Run(() {dt new DataTable();dt.Columns.Add(id, typeof(int));dt.Columns.Add(name);for (int i 0; i 10000; i){dt.Rows.Add(new object[] { i, name i.ToString() });}Thread.Sleep(1000);});return dt;}