异步编程 ASYNC AWAIT原理

一.通过指定Url下载数据(I/O 绑定)

通常我们是调用别人的异步方法,然后封装起来再用。

下面写一个异步方法

static async Task Main(string[] args)
        {
            await DownloadHtmlAsync("https://www.youzack.com", @"E:\a\1.txt");
            Console.WriteLine("ok");
        }

       static async Task DownloadHtmlAsync(string url,string filename)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                string html = await httpClient.GetStringAsync(url);
                await File.WriteAllTextAsync(filename, html);
            }

        }

提取出一个英语学习网站html   下载到对应的文件中

结果为

运行成功 

注意:

调用第三方类库的时候

如果同样的功能,既有同步方法,又有异步方法,那么首先使用异步方法。.NET5中 很多框架中的方法也都支持异步: Main、winForm事件处理函数。

对于不支持的异步方法怎么办? wait() (无返回值); Result (有返回值)。风险: 死锁。
尽量不用。

二.从网站Url获取返回的内容

private readonly HttpClient _httpClient = new HttpClient();
[HttpGet, Route("GetContent")]
public async Task<int> GetContent()
{
    //挂起GetContent()来允许调用者(web服务器)
    //接收另一个请求,而不是阻塞这个请求。
    var result = await _httpClient.GetStringAsync("https://dotnetfoundation.org");
    return result;
}

使用WinForm通过点击按钮使用HttpClient异步请求获取内容:

例如,

private readonly HttpClient _httpClient = new HttpClient();
private async void OnGetContentButtonClick(object sender, RoutedEventArgs e)
{
    // //捕获任务句柄,以便稍后等待后台任务。
    var getContentFoundationHtmlTask = _httpClient.GetStringAsync("https://dotnetfoundation.org");
    // UI线程上的任何其他工作都可以在这里完成,例如启用一个进度条。
    //这是很重要的,在"await"调用之前,以便用户
    //在执行此方法之前查看进度条。
    NetworkProgressBar.IsEnabled = true;
    NetworkProgressBar.Visibility = Visibility.Visible;
    //等待操作符挂起OnGetContentButtonClick(),将控制返回给调用者。
    //这是什么允许应用程序响应,而不是阻塞UI线程。
    var result = await GetContentFoundationHtmlTask;
    DotNetCountLabel.Text = result;
    NetworkProgressBar.IsEnabled = false;
    NetworkProgressBar.Visibility = Visibility.Collapsed;
}

 

三、API异步方法以及async和await关键字
.NET Framework 4.5 或更高版本以及 .NET Core 包含许多可与 async 和 await 结合使用的成员。 可以通过追加到成员名称的“Async”后缀和 Task 或 Task<TResult> 的返回类型,识别这些成员。 例如,System.IO.Stream 类包含 CopyToAsyncReadAsync 和 WriteAsync 等方法,以及同步方法 CopyToRead 和 Write

异步方法旨在成为非阻止操作。 异步方法中的 await 表达式在等待的任务正在运行时不会阻止当前线程。 相反,表达式在继续时注册方法的其余部分并将控件返回到异步方法的调用方。async 和 await 关键字不会创建其他线程。 因为异步方法不会在其自身线程上运行,因此它不需要多线程。

只有当方法处于活动状态时,该方法将在当前同步上下文中运行并使用线程上的时间。 可以使用 Task.Run 将占用大量 CPU 的工作移到后台线程,但是后台线程不会帮助正在等待结果的进程变为可用状态。

async 和 await的作用:

1)标记的异步方法可以使用 await 来指定暂停点。 await 运算符通知编译器异步方法:在等待的异步过程完成后才能继续通过该点。 同时,控制返回至异步方法的调用方。 异步方法在 await 表达式执行时暂停并不构成方法退出,只会导致 finally 代码块不运行。

2)标记的异步方法本身可以通过调用它的方法等待。

异步方法通常包含 await 运算符的一个或多个实例,但缺少 await 表达式也不会导致生成编译器错误。 如果异步方法未使用 await 运算符标记暂停点,则该方法会作为同步方法执行,即使有 async 修饰符,也不例外。 编译器将为此类方法发布一个警告。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值