c# 异步编程 学习笔记
2017-03-27 17:23
471 查看
/*异步编程
* 什么是异步编程,就是在不影响主程序线程的情况下,调用新的线程,去处理新的任务。让主程序县城可以继续执行其他任务。通常用在
* 耗时比较长的任务上,查询数据库,打开大型文件
*
* 和同步的区别:
* 同步:执行完一个操作后主程序才能执行下一个操作,有着固定的顺序
* 异步:在主程序执行一个操作时,异步操作可以在同时进行
* 本质就是重新开启了一个线程 主程序线程和方法线程并行执行
*
* 和多线程的区别:
* 首先,线程是程序提供的一种逻辑功能,他需要cpu的资源
* 异步操作不需要额外的线程,自然也就没有CPU的压力,使用回调的方式进行处理,而且对于共享变量的使用较少,不容易造成死锁,
* 但是顺序不符合普通人的思维
* 多线程需要启动额外的线程,需要消耗CPU资源。处理程序是顺序执行的。额外的线程容易对程序造成负担,共享变量容易造成死锁
*
* 异步模式
* 1异步模式
* 2基于事件的异步模式
* 3基于任务的异步模式
*
*/
下面举一个最普通的异步执行的例子
定义一个文件读取类
class fileReader
{
/// <summary>
/// 缓存池
/// </summary>
byte[] buffer;
/// <summary>
/// 缓存区大小
/// </summary>
private int buffsize;
public int Buffsize { get => buffsize; set => buffsize = value; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="buffsize">缓存区大小 </param>
public fileReader( int buffsize)
{
Buffsize = buffsize;
this.buffer = new byte[Buffsize];
}
/// <summary>
/// 同步读取文件
/// </summary>
/// <param name="path">文件路径</param>
public void SynsReadFile(string path)
{
Console.WriteLine("syns read File now begin");
if (File.Exists(path))
{
FileStream fs = new FileStream(path,FileMode.Open);
fs.Read(buffer, 0, Buffsize);
string output = Encoding.UTF8.GetString(buffer);
Console.WriteLine("now the file is " + output);
}
}
/// <summary>
/// 异步读取文件
/// </summary>
/// <param name="path">文件路径</param>
public void AsynReadFile(string path)
{
Console.WriteLine("asyn read file now begin");
if (File.Exists(path))
{
FileStream fs = new FileStream(path, FileMode.Open);
fs.BeginRead(buffer, 0, Buffsize,AsyncReadFileCallBack,fs);
}
}
/// <summary>
/// 异步读取的回调
/// </summary>
/// <param name="ar"></param>
public void AsyncReadFileCallBack(IAsyncResult ar)
{
FileStream fs = ar.AsyncState as FileStream;
if (fs != null)
{
Thread.Sleep(1000);
fs.EndRead(ar);
fs.Close();
string output = Encoding.UTF8.GetString(buffer);
Console.WriteLine("now the file is " + output);
}
}
}
然后再主程序中
static void Main(string[] args)
{
//同步执行和异步执行的例子
fileReader reader = new fileReader(1024);
string path = "C:\\Users\\v-chli1\\Desktop\\e-mail.txt";
Console.WriteLine(" put an enter to start reading file");
Console.ReadLine();
Console.WriteLine(DateTime.Now);
//reader.SynsReadFile(path);
reader.AsynReadFile(path);
Console.WriteLine("Next step");
testMethod();
}
/// <summary>
/// 测试方法
/// </summary>
static void testMethod()
{
Thread.Sleep(1000);
Console.WriteLine(DateTime.Now);
for (int i = 0; i<=777;i++)
{
if (i % 777 == 0)
Console.WriteLine("the number is " + i);
}
}
接下来是使用async 和await关键字的,基于任务的异步编程 方法
* async 和await 关键字
* async 修饰符只能用于返回Task和void的方法
* await 只能用于返回Task的方法
*
* 一个方法 添加了async 就表示这是一个异步方法
* await 关键词用在调用方法事时,处理Async 后缀的异步方法
* task.run 会创建一个线程池里的线程
*
*
* Async方式,使用Async标记的方法为异步方法,用Await标记方法c表示方法内需要耗时的操作。主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑。当await耗时操作完成时,继续执行Async方法下面的逻辑
* 使用这两个关键字时
* 1,首先创建一个普通方法(也可以省略直接写在异步化方法里)
* 2,创建一个task方法,方法名需要async作为后缀 ,返回值需要是Task或者Void,也可以Task<泛型>。然后用task.run 返回一个任务。调用普
4000
通方法或者直接将方法写入
* 3. 创建异步方法,需要用关键字async,调用前面的task 方法时,需要使用await 关键字,通知主线程去执行其他代码。等await 方法结束之后,才会继续带哦用异步方法中的后面
* 的代码
* 4.如果有continueWith 方法,则结束后继续执行此代码块中的代码
*
//异步代码
public static string Greeting(string name)
{
Thread.Sleep(2000);
return string.Format("Hello , {0}", name);
}
/// <summary>
/// 创建任务
/// </summary>
/// <param name="name">参数</param>
/// <returns></returns>
static Task<string> GreetingAsync(string name)
{
return Task.Run<string>(() =>
{
return Greeting(name);
});
}
/// <summary>
/// 调用异步方法
/// </summary>
private async static void callerWithAsync()
{
string result = await GreetingAsync("bob");
Console.WriteLine(result);
}
/// <summary>
/// continuewith 方法
/// </summary>
private static void CallerWithContinuationTask()
{
Task<string> t1 = GreetingAsync("david");
t1.ContinueWith(
t => {
string result = t.Result;
Console.WriteLine(result+"123");
}
);
}
private static async void MultipleAsyncMethods()
{
string s1 = await GreetingAsync("logan");
string s2 = await GreetingAsync("charles");
Console.WriteLine("methods finished " + s1 +" "+ s2);
}
private static async void MultipleAsyncMethodsWithCombinator()
{
Task<string> s1 = GreetingAsync("logan1");
Task<string> s2 = GreetingAsync("charles1");
await Task.WhenAll(s1,s2);
Console.WriteLine("methods finished " + s1.Result + " " + s2.Result);
}
private static async void MultipleAsyncMethodsWithCombinator2()
{
Task<string> s1 = GreetingAsync("logan2");
Task<string> s2 = GreetingAsync("charles2");
await Task.WhenAny(s1, s2);
Console.WriteLine("methods finished " + s1.Result + " " + s2.Result);
}
然后主程序中的代码
static void Main(string[] args)
{
MultipleAsyncMethodsWithCombinator2();
callerWithAsync();
CallerWithContinuationTask();
MultipleAsyncMethods();
MultipleAsyncMethodsWithCombinator();
}
* 什么是异步编程,就是在不影响主程序线程的情况下,调用新的线程,去处理新的任务。让主程序县城可以继续执行其他任务。通常用在
* 耗时比较长的任务上,查询数据库,打开大型文件
*
* 和同步的区别:
* 同步:执行完一个操作后主程序才能执行下一个操作,有着固定的顺序
* 异步:在主程序执行一个操作时,异步操作可以在同时进行
* 本质就是重新开启了一个线程 主程序线程和方法线程并行执行
*
* 和多线程的区别:
* 首先,线程是程序提供的一种逻辑功能,他需要cpu的资源
* 异步操作不需要额外的线程,自然也就没有CPU的压力,使用回调的方式进行处理,而且对于共享变量的使用较少,不容易造成死锁,
* 但是顺序不符合普通人的思维
* 多线程需要启动额外的线程,需要消耗CPU资源。处理程序是顺序执行的。额外的线程容易对程序造成负担,共享变量容易造成死锁
*
* 异步模式
* 1异步模式
* 2基于事件的异步模式
* 3基于任务的异步模式
*
*/
下面举一个最普通的异步执行的例子
定义一个文件读取类
class fileReader
{
/// <summary>
/// 缓存池
/// </summary>
byte[] buffer;
/// <summary>
/// 缓存区大小
/// </summary>
private int buffsize;
public int Buffsize { get => buffsize; set => buffsize = value; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="buffsize">缓存区大小 </param>
public fileReader( int buffsize)
{
Buffsize = buffsize;
this.buffer = new byte[Buffsize];
}
/// <summary>
/// 同步读取文件
/// </summary>
/// <param name="path">文件路径</param>
public void SynsReadFile(string path)
{
Console.WriteLine("syns read File now begin");
if (File.Exists(path))
{
FileStream fs = new FileStream(path,FileMode.Open);
fs.Read(buffer, 0, Buffsize);
string output = Encoding.UTF8.GetString(buffer);
Console.WriteLine("now the file is " + output);
}
}
/// <summary>
/// 异步读取文件
/// </summary>
/// <param name="path">文件路径</param>
public void AsynReadFile(string path)
{
Console.WriteLine("asyn read file now begin");
if (File.Exists(path))
{
FileStream fs = new FileStream(path, FileMode.Open);
fs.BeginRead(buffer, 0, Buffsize,AsyncReadFileCallBack,fs);
}
}
/// <summary>
/// 异步读取的回调
/// </summary>
/// <param name="ar"></param>
public void AsyncReadFileCallBack(IAsyncResult ar)
{
FileStream fs = ar.AsyncState as FileStream;
if (fs != null)
{
Thread.Sleep(1000);
fs.EndRead(ar);
fs.Close();
string output = Encoding.UTF8.GetString(buffer);
Console.WriteLine("now the file is " + output);
}
}
}
然后再主程序中
static void Main(string[] args)
{
//同步执行和异步执行的例子
fileReader reader = new fileReader(1024);
string path = "C:\\Users\\v-chli1\\Desktop\\e-mail.txt";
Console.WriteLine(" put an enter to start reading file");
Console.ReadLine();
Console.WriteLine(DateTime.Now);
//reader.SynsReadFile(path);
reader.AsynReadFile(path);
Console.WriteLine("Next step");
testMethod();
}
/// <summary>
/// 测试方法
/// </summary>
static void testMethod()
{
Thread.Sleep(1000);
Console.WriteLine(DateTime.Now);
for (int i = 0; i<=777;i++)
{
if (i % 777 == 0)
Console.WriteLine("the number is " + i);
}
}
接下来是使用async 和await关键字的,基于任务的异步编程 方法
* async 和await 关键字
* async 修饰符只能用于返回Task和void的方法
* await 只能用于返回Task的方法
*
* 一个方法 添加了async 就表示这是一个异步方法
* await 关键词用在调用方法事时,处理Async 后缀的异步方法
* task.run 会创建一个线程池里的线程
*
*
* Async方式,使用Async标记的方法为异步方法,用Await标记方法c表示方法内需要耗时的操作。主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑。当await耗时操作完成时,继续执行Async方法下面的逻辑
* 使用这两个关键字时
* 1,首先创建一个普通方法(也可以省略直接写在异步化方法里)
* 2,创建一个task方法,方法名需要async作为后缀 ,返回值需要是Task或者Void,也可以Task<泛型>。然后用task.run 返回一个任务。调用普
4000
通方法或者直接将方法写入
* 3. 创建异步方法,需要用关键字async,调用前面的task 方法时,需要使用await 关键字,通知主线程去执行其他代码。等await 方法结束之后,才会继续带哦用异步方法中的后面
* 的代码
* 4.如果有continueWith 方法,则结束后继续执行此代码块中的代码
*
//异步代码
public static string Greeting(string name)
{
Thread.Sleep(2000);
return string.Format("Hello , {0}", name);
}
/// <summary>
/// 创建任务
/// </summary>
/// <param name="name">参数</param>
/// <returns></returns>
static Task<string> GreetingAsync(string name)
{
return Task.Run<string>(() =>
{
return Greeting(name);
});
}
/// <summary>
/// 调用异步方法
/// </summary>
private async static void callerWithAsync()
{
string result = await GreetingAsync("bob");
Console.WriteLine(result);
}
/// <summary>
/// continuewith 方法
/// </summary>
private static void CallerWithContinuationTask()
{
Task<string> t1 = GreetingAsync("david");
t1.ContinueWith(
t => {
string result = t.Result;
Console.WriteLine(result+"123");
}
);
}
private static async void MultipleAsyncMethods()
{
string s1 = await GreetingAsync("logan");
string s2 = await GreetingAsync("charles");
Console.WriteLine("methods finished " + s1 +" "+ s2);
}
private static async void MultipleAsyncMethodsWithCombinator()
{
Task<string> s1 = GreetingAsync("logan1");
Task<string> s2 = GreetingAsync("charles1");
await Task.WhenAll(s1,s2);
Console.WriteLine("methods finished " + s1.Result + " " + s2.Result);
}
private static async void MultipleAsyncMethodsWithCombinator2()
{
Task<string> s1 = GreetingAsync("logan2");
Task<string> s2 = GreetingAsync("charles2");
await Task.WhenAny(s1, s2);
Console.WriteLine("methods finished " + s1.Result + " " + s2.Result);
}
然后主程序中的代码
static void Main(string[] args)
{
MultipleAsyncMethodsWithCombinator2();
callerWithAsync();
CallerWithContinuationTask();
MultipleAsyncMethods();
MultipleAsyncMethodsWithCombinator();
}
相关文章推荐
- c# 异步编程 学习笔记
- C#2005 .NET3.0高级编程学习笔记————流控制
- C#2005 .NET3.0高级编程学习笔记————类和结构,类的数据成员,类的函数成员(方法、属性)
- C#学习笔记24——数据库编程
- 黑马程序员之C#编程基础学习笔记:交换两个变量的值。
- [C#学习笔记之异步编程模式3]异步下载web网页
- C#2005 .NET3.0高级编程学习笔记————命名空间
- 深入.NET平台和C#编程 第二章 学习笔记
- C#学习笔记28——C# 插件编程
- 深入.NET平台和C#编程 第四章 学习笔记
- 黑马程序员之C#编程基础学习笔记:让用户输入一个半径,打印出圆的面积。
- C#2005 .NET3.0高级编程学习笔记————类和结构,类的数据成员,类的函数成员(方法、属性)
- 深入.NET平台和C#编程 第一章 学习笔记
- C#2005 .NET3.0高级编程学习笔记————继承
- [学习笔记]C#编程基础1
- C#2005 .NET3.0高级编程学习笔记———.NET体系结构
- C#2005 .NET3.0高级编程学习笔记————类的函数成员(构造函数,只读字段)
- C#网络编程学习笔记1
- C#2005 .NET3.0高级编程学习笔记————结构,部分类,静态类,Object类
- 《Web Service 编程 --用C#.NET 开发网络服务》北京希望出版社 我的学习笔记(第二章)(也就是书上抄了一写东西而已)