C# 理解多线程和异步,await/async方法的使用

2 篇文章 0 订阅

程序运行的时候是同步的 但是他在同步的时候遇到一个需要等待一段时间得到结果的代码段时 他就不会执行下面的代码 而是等待完成后在执行 但是这个代码段只是执行就可以了 和下面的程序段也没有什么冲突的地方 那么 这个时候可以开启新的线程去处理它
让主程序继续运行
每次遇到需要等待的一些方法 我一般是使用多线程进行处理
比如 new Thread(()=>{/}).start();
但是后来我喜欢用C#的Task(开启任务线程)
new Task(()=>{/}).start()
Task.Run(()=>{/});//官方推荐
Task.Factory.StarNew(()=>{});
那这两者有什么区别呢
new Thread()是开启一个一个陪伴程序到结束的线程
频繁的去new Thread()会消耗大量内存
而Task 是在线程池里面
使用完后会被回收 避免内存浪费

那什么是异步? 那当然是和同步不一样才叫异步
异步指的是让CPU暂时搁置当前请求的响应,处理下一个请求,当通过轮询或其他方式得到回调通知后,开始运行

看一个异步的例子

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AwaitWithAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            MyDownLoadString ds = new MyDownLoadString();
            ds.DoRun();
            Console.ReadKey();
        }

        class MyDownLoadString
        {
            Stopwatch sw = new Stopwatch();
            public void DoRun()
            {
                const int LargeNumber = 60000000;
                sw.Start();
                // Task<int> 保存结果对象,后面t1.Result则是获取结果
                Task<int> t1 = CountCharactersAsync(1, "http://www.microsoft.com");
                Task<int> t2 = CountCharactersAsync(2, "http://www.illustratedcsharp.com");

                //无需等待CountCharactersAsync执行完成
                CountToALargeNumber(1, LargeNumber);
                CountToALargeNumber(2, LargeNumber);
                CountToALargeNumber(3, LargeNumber);
                CountToALargeNumber(4, LargeNumber);

                //t1.Result获取结果
                Console.WriteLine("Chars in Call1:{0}", t1.Result);
                Console.WriteLine("Chars in Call1:{0}", t2.Result);
            }

            private async Task<int> CountCharactersAsync(int id, string uriString)
            {
                WebClient wc = new WebClient();
                Console.WriteLine("Call {0} start: {1:N0}ms ", id, sw.Elapsed.TotalMilliseconds);
                string result = await wc.DownloadStringTaskAsync(new Uri(uriString));
                Trace.TraceInformation("Taceing Async Call {0} @time:{1:N0}ms", id, sw.Elapsed.TotalMilliseconds);
                Console.WriteLine("Call {0} completed: {1:N0}ms", id, sw.Elapsed.TotalMilliseconds);
                return result.Length;
            }

            private void CountToALargeNumber(int id, int value)
            {
                for (long i = 0; i < value; i++) ;
                Console.WriteLine("End CountToALargeNumber {0}: {1:N0}ms", id, sw.Elapsed.TotalMilliseconds);
            }
        }
    }

}

在这里插入图片描述
当LargeNumber是60000000时 运行
在这里插入图片描述
可以看到程序并不是顺序执行的
在调用计算的中期 第二个异步方法就已经执行完成了
第一个异步方法最后才完成
因为await花费的时间不一样
连接不顺畅的时候 甚至出现了这样的情况
在这里插入图片描述
在没有得到回调通知前 他们都在等待着没有执行
其他的代码照常运作 等到回调成功后 才执行完成

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值