.net 异步编程

99 阅读1分钟

特点

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

  1. 异步方法的返回值一般是Task < T >,T是真正的返回值类型,Task< int >。

    惯例: 异步方法名字以Async结尾。

  2. 即使方法没有返回值,也最好把返回值声明为非泛型的Task。

    一般在方法前加上await关,这样拿到的返回值就是泛型指定的T类型

  3. 调用泛型方法时,一个方法中如果有await调用,则这个方法也必须修饰为async

案例

demo1

创建一个写操作

原方法

string filename = @"Z:\file\1.txt";
File.WriteAllText(filename, "hello");
string s = File.ReadAllText(filename);
Console.WriteLine(s);

异步方法

string filename2 = @"Z:\file\2.txt";
await File.WriteAllTextAsync(filename2, "hello");
Task<string> task = File.ReadAllTextAsync(filename2);
string result = await task;
Console.WriteLine(result);

image.png

demo2

根据给定的地址,下载对应的网页,并返回长度

static async Task<int> DownloadHtml(string url,string filename)
{
   using (HttpClient client = new HttpClient())
    {
        string html = await client.GetStringAsync(url);
        await File.WriteAllTextAsync(filename, html);
        return html.Length;
    }

}

int len = await DownloadHtml("https://www.baidu.com/", @"Z:\file\3.txt");
Console.WriteLine(len);

image.png

Result

如果无法调用异步方法,可手动取出值来 => Task.Result

image.png

Wait

image.png

async 方法缺点

image.png

  1. 异步方法会生成一个类,运行效率没有普通方法高
  2. 可能会占用非常多的线程

直接返回Task

image.png

线程暂停

如果想要在异步方法中暂停一段时间,

不要用Thread.Sleep(),因为他会阻塞调用的线程

而要用await Task().Delay()