一.什么是异步
启动程序时,系统会在内存中创建一个新的进程。进程是构成运行程序的资源的集合。这些资源包括虚地址空间、文件句柄和许多其他程序运行所需的东西。
在进程内部,系统创建了一个称为线程的内核(kernel)对象,它代表了真正执行的程序。(线程是“执行线程”的简称。)一旦进程建立,系统会在Nain方法的第一行语句处就开始线程的执行
在异步程序中,程序代码不需要按照编写时的顺序严格执行。有时需要在一个新的线程中运行一部分代码,有时无需创建新的线程,但为了更好地利用单个线程的能力,需要改变代码的执行顺序
- 在C#5.0中引入的一个用来构建异步方法的新特性——async/await
- .NET框架的特性——BackgroundWorker类 和 .NET任务并行库(没有嵌入C#中)
C#关键字:async、await、
async、await不等于多线程
1.异步方法:
“异步方法”:用async关键字修饰的方法
1)异步方法的返回值一般是Task<T>,T是真正的返回值类型,Task<int>。惯例: 异步方法名字以Async结尾。
2)即使方法没有返回值,也最好把返回值声明为非泛型的Task。
3)调用泛型方法时,一般在方法前加上await关键字,这样拿到的返回值就是泛型指定的T类型
4)异步方法的“传染性”:一个方法中如果有await调用,则这个方法也必须修饰为async
同步
String filename = @"E:\a\1.txt";
File.WriteAllText(filename, "hello");
string s = File.ReadAllText(filename);
Console.WriteLine(s);
运行结果
异步方法:
string filename = @"E:\a\1.txt";
await File.WriteAllTextAsync(filename, "hello 你好");
string s = await File.ReadAllTextAsync(filename);
Console.WriteLine(s);
结果是正常写入
还有一种比如写入量特别大的字符串就会出现异常
string filename = @"E:\a\1.txt";
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 100000; i++)
{
sb.AppendLine("hello");
}
File.WriteAllTextAsync(filename, sb.ToString());
string s = await File.ReadAllTextAsync(filename);
Console.WriteLine(s);
这种写入量特别大的字符串然后在读出来就会报异常
The process cannot access the file 'E:\a\1.txt' because it is being used by another process.”
进程无法访问文件“E:\a\1.txt”,因为另一个进程正在使用该文件。“
说明写入是同步进程 下边的读取用await修饰是异步进程
一边正在写入还没有写入完毕 另一边就去读取了 就会出现异常
但是在
位置加上await就不会出现异常
加上await 那么就会写入完毕才会就行读取
string filename = @"E:\a\1.txt";
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 100000; i++)
{
sb.AppendLine("hello");
}
await File.WriteAllTextAsync(filename, sb.ToString());
string s = await File.ReadAllTextAsync(filename);
Console.WriteLine(s);
结果