C#之异步执行

0 什么是异步执行

异步(asynchronous)执行他还有个 兄弟是 同步执行(Synchronous)

同步执行呢

程序只能干一件事情, 干完一件 再干一件,中间还不能打扰他,反正他也不理, 一打扰一气之下就给你个未响应 ,让你干瞪眼. 你说气不气

异步执行就不一样了

程序进化了,他智商提高了..他可以三心二用了

一个程序他可以分开干,也可给他多任务做,不比顺序执行任务

有一个非常经典例子

界面上点击按钮 下载文件 

如果在同步执行的话,需要等待文件下载完,界面才可以点击,相当不人性化操作

在异步执行中呢

我可以新开一个线程去下载这玩意,让他下载完了,我再去操作下载的文件,不用干等着下载

这时候界面还可以点,不会出现卡顿的现象,极大的提高了操作性.

1 异步的实现

异步的实现也经历了好多代的演变,

现在常用的是

Task 和 Task<T> 类型 和async 和 await 关键字

任务

任务是用于实现称之为并发 Promise 模型的构造。 简单地说,它们“承诺”,会在稍后完成工作,让你使用干净的 API 与 promise 协作。

这是MSDN的解释

值的注意的是,任务并不是简单的新开一个线程,

而是在现有的进程有用的线程中休眠的进行工作,如果没有的话休眠的线程再新开线程,减少开销

中间做了一些包装.有兴趣的可以去研究一下

任务的取消(可选)

取消是异步方法实现者和异步方法使用者的选项。 如果操作允许取消,则会公开接受取消标记(CancellationToken 实例)的异步方法的重载。 按照约定,该参数命名为 cancellationToken

例如:

public Task ReadAsync(byte [] buffer, int offset, int count, CancellationToken cancellationToken)

不过值得注意的是

任务的取消是逻辑取消.

需要自己在程序中判断

如果程序中没有判断这个表示

在任务上取消也是没有用,程序还是一直跑下去的

还有一些其他操作

例如任务的进度啊Task.whenAll什么.这里就不展开了..

async/await

async 标明是异步方法(其实没太大用处,主要是用于兼容)

await 执行挂起

等待 Task 时,await 表达式的类型为 void。 等待 Task<TResult> 时,await 表达式的类型为 TResult。 await 表达式必须出现在异步方法的正文内。 (.NET Framework 4.5 中引入了这些语言功能)

 class Program
    {
        static void Main(string[] args)
        {
            var str = TestAsync().Result;
            Console.WriteLine(str);
            Console.WriteLine($"{DateTime.Now.ToString("ss.fff")} 测试点一");
            Console.ReadKey();
        }

        public static async Task<string> TestAsync()
        {
            var re = string.Empty;
            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine($"{DateTime.Now.ToString("ss.fff")} 测试点二");
                re += $"当前任务一线程为:{Thread.CurrentThread.ManagedThreadId}";
                Console.WriteLine("函数体内"+re);
            });
            await Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine($"{DateTime.Now.ToString("ss.fff")} 测试点三");
                re += $"当前任务二线程为:{Thread.CurrentThread.ManagedThreadId}";
                Console.WriteLine("函数体内"+re);

            });
            return re;
        }
    }

函数的输出结果

可以看出任务二 有了关键字 await 的阻塞 ,等他跑完之后才返回 re

而任务一没有阻塞 ,所以并没有等他跑完,就返回了, 

虽然值返回了,但是任务还在跑 ,所以后面有继续输出

还有值得注意的Task.Resut获取结果时会阻塞线程,所以[测试点一] 这个日志当 re 输出后,才输出的

如果不需要取 Taks.Reuslt的话 ,并没有阻塞当前进程, 

持续学习中..

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值