C# 中的异步方法中的await和async、Result、 wait()

感谢书籍《ASP.NET Core 技术内幕与项目实战》及其作者杨中科。

“异步方法”:用async 关键字修饰的方法

  1. 异步方法的返回值一般是Task,T是真正的返回数据类型,如Task。惯例:异步方法名字以Async结尾。
  2. 如果方法无返回值,则应把返回值类型声明为Task。
  3. 调用泛型方法时,一般在方法前加上await,返回值就是泛型制定的T类型
  4. 一个方法如果有await调用,则这个方法也必须添加关键字async

```csharp
```csharp
```csharp
 static void Main(string[] args)
        {
            string filename = "f:/1.txt";
            File.Delete(filename);
            File.WriteAllTextAsync(filename, "hello world");
            string conttent =await File.ReadAllTextAsync(filename);
            Console.WriteLine(conttent);
        }
```csharp

提示编译错误如下:
在这里插入图片描述

Main函数声明添加async:


`

```csharp
``csharp
  static async Task Main(string[] args)
        {
            string filename = "f:/1.txt";
            File.Delete(filename);
            File.WriteAllTextAsync(filename, "hello world");
            string conttent =await File.ReadAllTextAsync(filename);
            Console.WriteLine(conttent);

        }


**疑问: File.WriteAllTextAsync(filename, "hello world");  为什么不用await 也能成功执行?**
注意看下面的例子:

```csharp
 string filename = "f:/1.txt";
            File.Delete(filename);
            StringBuilder strb = new StringBuilder();
            for (int i = 0; i < 1000000; i++)
            {
                strb.Append(i.ToString());
            }
            File.WriteAllTextAsync(filename, strb.ToString());
            Console.WriteLine(await File.ReadAllTextAsync(filename));

如上图,
Console.WriteLine(await File.ReadAllTextAsync(filename));
执行异常:
System.IO.IOException:“The process cannot access the file ‘f:\1.txt’ because it is being used by another process.”
提示 文件正在被其它进程操作。
猜想:可能是前面的File.WriteAllTextAsync(filename, strb.ToString());写入文件内容比较多,调用没有用await 修饰,所以程序没有等待File.WriteAllTextAsync(filename, strb.ToString());执行完毕,文件的句柄没有释放,就被 Console.WriteLine(await File.ReadAllTextAsync(filename));访问,所以打开了没有释放的文件句柄,就会提示错误。
验证如下File.WriteAllTextAsync(filename, strb.ToString()); 前加上await

   string filename = "f:/1.txt";
            File.Delete(filename);
            StringBuilder strb = new StringBuilder();
            for (int i = 0; i < 1000000; i++)
            {
                strb.Append(i.ToString());
            }
            await File.WriteAllTextAsync(filename, strb.ToString());
            Console.WriteLine(await File.ReadAllTextAsync(filename));

```csharp
正常执行,且能正常输出内容。

**疑问2:一些系统定义的函数如winform 中的事件函数,调用了一步Async 方法,如何改变方法名称?**
 wait() (无返回值) ; Result (有返回值) 。风险:死锁。
 如下:

```csharp
 static async Task<string> WriteFileAsync(int times,string filename)
        {
            File.Delete(filename);
            StringBuilder strb = new StringBuilder();
            for (int i = 0; i < times; i++)
            {
                strb.Append(i.ToString());
            }
            await File.WriteAllTextAsync(filename, strb.ToString());
            String str =await File.ReadAllTextAsync(filename);
            return str;
        }
private void button1_Click(object sender, EventArgs e)
        {
            string filename = "f:/1.txt";

            string length = WriteFileAsync(500, filename).Result;
            MessageBox.Show(length.ToString());
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#async和await是用于异步编程的关键字,可以让开发者更方便地进行异步编程。下面是async和await的详细使用方法: 1. 异步方法的定义 在定义异步方法时,需要在方法前面加上async关键字。异步方法的返回值类型必须是Task或Task<TResult>。 ```csharp public async Task<int> DoAsync() { //执行异步操作 return 1; } ``` 这里定义了一个异步方法DoAsync,该方法返回一个Task<int>对象,包含异步操作的返回值。 2. 异步方法的调用 在调用异步方法时,需要在方法前面加上await关键字。await会等待异步方法执行完成,并获取其返回值。 ```csharp int result = await DoAsync(); ``` 这里调用DoAsync方法,并使用await关键字等待其执行完成,并获取其返回值。 3. 异步方法的异常处理 在异步方法可能会发生异常,需要使用try/catch语句来捕获异常。异步方法的异常可以使用throw语句抛出,也可以使用Task.FromException方法创建一个Task对象来表示异常。 ```csharp public async Task<int> DoAsync() { try { //执行异步操作 return 1; } catch(Exception ex) { //处理异常 throw ex; } } ``` 4. 异步方法的延续操作 在异步方法可以使用await关键字来等待另一个异步方法执行完成,并在其执行完成后执行一些操作。 ```csharp public async Task<int> DoAsync() { int result = await Task.Run(() => { //执行异步操作 return 1; }); //处理异步操作执行结果 return result; } ``` 这里在异步方法调用Task.Run方法执行另一个异步操作,使用await关键字等待其执行完成,并获取其返回值。 5. Task的等待 在异步方法,可以使用Task的Wait方法等待异步操作执行完成。需要注意的是,使用Wait方法会阻塞当前线程,因此需要在后台线程执行异步操作。 ```csharp public async Task<int> DoAsync() { Task<int> task = Task.Run(() => { //执行异步操作 return 1; }); task.Wait(); //处理异步操作执行结果 return task.Result; } ``` 这里使用Task.Wait方法等待异步操作执行完成,并使用Task.Result属性获取异步操作的返回值。 以上就是async和await的一些常用使用方法,利用async和await可以更方便地进行异步编程。需要注意的是,在使用async和await时需要注意线程安全问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值