[空白_录音] 嗨,你好,下面一起来学习异步编程
异步编程可以说是 C# 里面呢最大的一个优势了
在别的语言里面异步编程相当困难,但是在我们 C#里头相当方便。
这个异步呢它 是相对于同步而言的,我们简单的说呢就是,同步的意思就是一件事情接一件事情,一件件事情
必须头一件事情做完了,第二件事情呢再接着做,那么异步呢就是我们做一件事情的时候呢
同时呢也可以做另外的事情。
异步呢在一定意义上可以用线程来实现 当然也可以不用线程来实现,只不过我们在
C# 呢这个比较高级的这个编程的情况下呢 基本上都是用线程来实现的。
那么这个异步它主要解决的问题 就是一些,等待一些耗时的任务的时候,特别是比如说我们要
取文件啊,从文件里读写啊,或者是要跟网络里面获取信息的时候,耗时间的
那在这个过程当中如果我们在一个按钮里面 比如说去获取网络上的信息,我们就要等很长时间,那个界面呢
它就没法接着做别的事情,所以就造成阻塞 异步呢它就是解决这个问题,就是要不阻塞当前的任务
它主要的就是提高了这个程序啊的 响应能力,特别是这个 UI,也就是我们的界面的响应能力
因为异步呢就是把那另外一个任务在另一个线程当中执行啊,本线程呢可以接着做别的事情 然后等待那个任务执行完毕。
我们下面看 一个例子,这里面呢要做别的事情,传统的办法呢 就是使用委托,啊使用委托。
任何一个委托呢它都有一个 BeginInvoke 和
EndInvoke,就是开始调用 当然开始调用这个委托也就是调用委托里的方法了,开始调用,然后呢就把这个
委托呢里面的任务呢用另外一个线程去执行,同时呢主线程可以继续执行。
你看这里是这样的 假设我们这里有个委托,它里面的包装的就是有个函数的一个方法了
这个委托呢 BeginInvoke,那就开始在别的线程就去执行了
然后程序呢又回到这个我们这个线程这个地方呢继续执行。
所以这样的话 等于就是另外一个事情呢是独立的、
分开地去做,嗯异步地去做,然后我们这里 呢可以继续往下走。
然后做到一定程度情况呢我们需要一个 EndInvoke
去等待那个另一个任务呢执行完毕,所以这个 EndInvoke
它有两个作用: 第一个呢是等待,另外呢我们可以呢获取它这个任务执行的结果 那么这个
EndInvoke 呢和 BeginInvoke 呢之间它有一个关联,这个关联呢就是一个异步调用接口
IAsyncResult,通过这两个 EndInvoke
呢表示我们调用的这么一个过程 那 EndInvoke 的时候我们可以呢使用刚才得到那个
对象呢带到 EndInvoke 里面去,那这两个呢就关联起来
所以这是一个,基本的一个方法,我们可以通过一个例子呢来看这个机制 请看这个例子:那这里呢有一个
Delegate 有一个委托,嗯它带一个字符串,返回一个整数
那当然这下面呢就是具体的这个函数呢,我们也就是做一些任务,比如这儿做一些显示,然后- 等待一会儿 返回呢一些数据。
那在这里面我们为了异步地去执行 刚才这个复方法啊,那我们先把这个复方法呢复制到也就是
创建到一个 Delegate 里面,这个 Delegate 呢就可以 BeginInvoke,就开始调用
这个开始调用的过程,这是带的参数,然后另外两个参数我们就忽略它
在这个过程当中,那主线程呢,就开始调用以后呢 这里面的函数因为它是比较耗时间呢,我们这里呢耗时一秒钟
所以呢它主线程呢可以接着往下走,然后 在必要的时候我们用
EndInvoke 去等待这个结果并且返回这个结果 然后呢又回到主线程。
那异步的开始执行的这个线程呢应该就是另一个线程 我们可以运行一下。
大家可以看到主线程呢这个线程号是 1 然后呢主线程呢,当我们调用完那个主线程的时候呢继续执行
而这个,另一个异步的那个方法呢它是在线程 3,嗯另一个线程上执行
然后执行完了以后呢又回到主线程,所以是这样一个过程 除了使用刚才
EndInvoke,然后 BeginInvoke 对应以外呢 我们也经常呢使用回调的方法来表示呢
它这个任务的执行呢,也就是说我们给它一个参数 就是这个一个回调函数,当然它也是一个
Delegate 那么这个回调函数呢它要求呢返回为
viod 类型 带着是一个什么参数呢?这个参数呢就是我们刚才
得到的一个 BeginInvoke 返回的一个那个对象。
在 BeginInvoke 可以带一个是回调函数,另外一个呢是带,一般情况呢我们可以带一个对象
但是呢最常见呢就是把这个 Delegate 本身也带进去
当这个任务执行完成以后,它就会调用这个回调函数。
这个回调函数呢 是一个里面呢我们可以用 EndInvoke 来取得这个结果,来取得结果。
所以通过这样一个过程 呢就跟我们刚才不一样的地方在于什么呢,就是有一个回调函数
在这个回调函数里头进行 EndInvoke
这是一个最常见的办法,这种办法呢好处就是我们可以把一个另一个任务呢
放到另一个线程里面去做。
当然这个线程的调度呢是由它的运行环境
来做的,像我们一般的像这种控制台应用程序啊,它会去调度另一个线程
所以大家可以思考一下,就是它会调另一个线程呢来执行某一个方法
那么这个方法完了以后呢它就要执行这个回调函数 那一般说来,这个回调函数是在主线程上执行呢还是在
这个我们刚才那个辅线,异步的那个线程上执行呢?
这个就是由它的,C# 的一个运行环境 来定的。
所以一般的情况下,像简单的控制台应用程序啊
它为了少少运用线程,所以呢它基本上这个回调函数的 这个线程呢也是
刚才我们新开辟的那个辅助线程,所以这一点呢要注意 当然这个是由这个环境决定的,如果它是在
这个 winform 程序,那它一般情况下这个回调函数呢
跟我们的那个界面的主线程呢是同一个线程。
所以这个 是总的来说呢吧,它来定这个线程之间的这个调度关系
两个线程啊,异步的 执行,同时呢它又可以呢互相关联