一.如何使用异步模式?

  异步模式是在处理流类型时经常采用的一种方式,其应用的领域相当广阔,包括读写文件、网络传输、读写数据库,甚至可以采用异步模式来做任何计算工作。相对于手动编写线程代码,异步模式是一个高效的编程模式。

  (1)所谓异步模式是个什么鬼?

     在启动一个操作之后可以继续执行其他工作而不会发生阻塞。

以读取文件为例,在同步模式下,当程序执行到Read方法时,需要等到读取动作结束后才能继续往下执行。而异步模式则可以简单地通知开始读取任务之后,继续其他的操作。 异步模式的优点就在于不需要使当前线程等待,而可以充分地利用CPU时间。

异步模式区别于线程池机制在于允许程序查看操作的执行状态,而利用线程池的后台线程,则无法确切地知道操作的进行状态以及其是否已经结束。

  使用异步模式可以通过一些异步聚集技巧来查看异步操作的结果,所谓的聚集技巧是指查看操作是否结束的方法,方式是:在调用BeingXXX方法时传入操作结束后需要执行的方法(又称为回调方法),同时把执行异步操作的对象传入以便执行EndXXX方法。

  (2)使用异步模式读取一个文件

  下面的示例代码中:

  ① 主线程中负责开始异步读取并传入聚集时需要使用的方法和状态对象:

    partial class Program
{
// 测试文件
private const string testFile = @"C:\AsyncReadTest.txt";
private const int bufferSize = ; static void Main(string[] args)
{
// 删除已存在文件
if (File.Exists(testFile))
{
File.Delete(testFile);
} // 写入一些东西以便后面读取
using (FileStream stream = File.Create(testFile))
{
string content = "我是文件具体内容,我是不是帅得掉渣?";
byte[] contentByte = Encoding.UTF8.GetBytes(content);
stream.Write(contentByte, , contentByte.Length);
} // 开始异步读取文件具体内容
using (FileStream stream = new FileStream(testFile, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous))
{
byte[] data = new byte[bufferSize];
// 将自定义类型对象实例作为参数
ReadFileClass rfc = new ReadFileClass(stream, data);
// 开始异步读取
IAsyncResult result = stream.BeginRead(data, , data.Length, FinshCallBack, rfc);
// 模拟做了一些其他的操作
Thread.Sleep( * );
Console.WriteLine("主线程执行完毕,按回车键退出程序");
} Console.ReadKey();
}
}

  ② 定义了完成异步操作读取之后需要调用的方法,其逻辑是简单地打印出文件的内容:

    partial class Program
{
/// <summary>
/// 完成异步操作后的回调方法
/// </summary>
/// <param name="result">状态对象</param>
private static void FinshCallBack(IAsyncResult result)
{
ReadFileClass rfc = result.AsyncState as ReadFileClass;
if (rfc != null)
{
// 必须的步骤:让异步读取占用的资源被释放掉
int length = rfc.stream.EndRead(result);
// 获取读取到的文件内容
byte[] fileData = new byte[length];
Array.Copy(rfc.data, , fileData, , fileData.Length);
string content = Encoding.UTF8.GetString(fileData);
// 打印读取到的文件基本信息
Console.WriteLine("读取文件结束:文件长度为[{0}],文件内容为[{1}]", length.ToString(), content);
}
}
}

  ③ 定义了作为状态对象传递的类型,这个类型对所有需要传递的数据包进行打包:

    /// <summary>
/// 传递给异步操作的回调方法
/// </summary>
public class ReadFileClass
{
// 以便回调方法中释放异步读取的文件流
public FileStream stream;
// 文件内容
public byte[] data; public ReadFileClass(FileStream stream,byte[] data)
{
this.stream = stream;
this.data = data;
}
}

  下图展示了该实例的执行结果:

  如上面的实例,使用回调方法的异步模式需要将异步操作的对象及操作的结果数据都打包到一个类型里以便能够传递回给回调的委托方法,这样在委托方法中才能够有机会处理操作的结果且调用EndXXX方法以释放资源。

.NET基础拾遗(7)多线程开发基础3的更多相关文章

  1. .NET基础拾遗(5)多线程开发基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  2. .NET基础拾遗(7)多线程开发基础4

    一.多线程编程中的线程同步 1.C#中的lock关键字 lock关键字可能是我们在遇到线程同步的需求时最常用的方式,但lock只是一个语法糖,为什么这么说呢,下面慢慢道来. (1)lock的等效代码其 ...

  3. .NET基础拾遗(7)多线程开发基础2

    二..NET中的多线程编程 2.1 如何在.NET程序中手动控制多个线程? 最直接且灵活性最大的,莫过于主动创建.运行.结束所有线程. (1)第一个多线程程序 .NET提供了非常直接的控制线程类型的类 ...

  4. .NET基础拾遗(7)多线程开发基础1

    一.多线程编程的基本概念 1.1 操作系统层面的进程和线程 (1)进程 进程代表了操作系统上运行着的一个应用程序.进程拥有自己的程序块,拥有独占的资源和数据且可以被操作系统调度. But,即使是同一个 ...

  5. (转).NET基础拾遗(5)多线程开发基础

    https://www.cnblogs.com/edisonchou/p/4848131.html

  6. ios多线程开发基础

    多线程编程:下载数据时,开辟子线程,减少阻塞时间,和主线程并发运行,提升用户体验 1.Thread 1>新建Thread对象,带一selector方法,调用start方法,开启子线程 2> ...

  7. .NET基础拾遗(6)ADO.NET与数据库开发基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

  8. .NET基础拾遗(7)Web Service的开发与应用基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

  9. .NET基础拾遗(1)类型语法基础和内存管理基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

随机推荐

  1. 你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都…

    4.3.3  for循环:某个范围内…每个都… 既然while语句和do…while…语句都已经可以满足我们表达循环现象的需要,那为什么C++还要专门提供for语句来表达循环现象呢?在现实世界中,常常 ...

  2. 多线程08-Callable和Future

    1.简介 Callable是一个接口,与Runnable类似,包含一个必须实现的call方法,可以启动为让另一个线程来执行,执行Callable可以得到一个Future对象 该对象可以监听Callab ...

  3. Bash shell 笔记总结(一) 转自http://www.bubuko.com/infodetail-509992.html,谢谢原作者

    本文是上课笔记总结,涉及细节知识点会在以后文章说明! bash脚本编程: 脚本程序:解释器解释执行: shell: 交互式接口:编程环境: shell: 能够提供一些内部命令,并且能通过PATH环境变 ...

  4. nodejs调试

    1.通过debug命令进行调试 node debug app.js 运行的结果: 在debug状态下输入"repl"命令可以评估变量和表达式的值 按下'CTRL+C'可以退出rep ...

  5. c#播放声音文件

    C#中声音的播放主要有三种方法: 1.使用API函数. 2.使用SoundPlayer类播放. 3.使用DirectX进行播放. 一.使用API函数进行播放. windows操作系统中的winmm.d ...

  6. C#实现打印与打印预览功能(转)

    在windows应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .Net Framework的打印功能都以组件的方式提供,为程序员提供了很大的方便,但是这 ...

  7. 《python基础教程》笔记之 序列通用操作

    索引 序列中的所有元素都是有编号的--从0开始递增.使用负数索引时,Python会从右边,也就是从最后一个元素开始计数,最后一个元素的位置编号是-1.此外,字符串是一个有字符组成的序列,字符串字面值可 ...

  8. IE11新特性 -- Internet Explorer 11:请不要再叫我IE

    Internet Explorer 11 中的一些新特性,包括对WebGL 的支持.预抓取.预渲染.flexbox.mutationobservers 以及其他一些 Web 标准的支持.但是更有趣的是 ...

  9. Reaver v1.4 用法整理 含高级参数说明 pin必备资料

    闲话少叙 使用方法: airmon-ng start wlan0 //启动mon0监控 reaver -i mon0 -b MAC -a -S -vv //普通用法 如果,90.9%进程后死机或停机, ...

  10. nosql newsql

    http://www.cnblogs.com/end/archive/2011/10/19/2217244.html http://www.csdn.net/article/2011-09-26/30 ...