博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第二十章:异步和文件I/O.(四)
阅读量:6858 次
发布时间:2019-06-26

本文共 3320 字,大约阅读时间需要 11 分钟。

与lambdas的警报

简化回调的一种显而易见的方法是使用lambda函数。 AlertLambdas程序证明了这一点。 XAML文件与AlertCallbacks方法中的相同,但响应按钮单击而发生的所有内容现在都在Clicked处理程序中:

public partial class AlertLambdasPage : ContentPage{    public AlertLambdasPage()    {        InitializeComponent();    }    void OnButtonClicked(object sender, EventArgs args)    {        Task
task = DisplayAlert("Simple Alert", "Decide on an option", "yes or ok", "no or cancel"); task.ContinueWith((Task
taskResult) => { Device.BeginInvokeOnMainThread(() => { label.Text = String.Format("Alert {0} button was pressed", taskResult.Result ? "OK" : "Cancel"); }); }); label.Text = "Alert is currently displayed"; }}

除了回调方法没有名称之外,这个程序和前一个程序之间没有什么区别。 他们是匿名的。 但有时lambda函数有可能模糊程序流,这当然就是这种情况。 在调用ContinueWith方法之后和传递给ContinueWith的回调执行之前,Label的Text属性设置为文本“当前显示警报”,但该语句出现在方法的底部。

在不扭曲程序流程的情况下,应该有更好的方法来表示您想要发生的事情。 这种更好的方式称为等待。
等待的警报
AlertAwait程序与AlertCallbacks和AlertLambdas具有相同的XAML文件,但OnButtonClicked方法大大简化:

public partial class AlertAwaitPage : ContentPage{    public AlertAwaitPage()    {        InitializeComponent();    }    async void OnButtonClicked(object sender, EventArgs args)    {        Task
task = DisplayAlert("Simple Alert", "Decide on an option", "yes or ok", "no or cancel"); label.Text = "Alert is currently displayed"; bool result = await task; label.Text = String.Format("Alert {0} button was pressed", result ? "OK" : "Cancel"); }}

关键声明是这样的:

bool result = await task;

该任务变量是从DisplayAlert返回的Task 对象,但是await关键字似乎神奇地提取了没有任何回调或lambda的布尔结果。

你应该知道的第一件事就是await实际上并没有等待警报被解雇!相反,C#编译器已经对OnButtonClicked方法进行了大量的手术。该方法基本上已经变成了状态机。单击按钮时将执行部分方法,稍后将执行部分方法。当执行流程命中await关键字时,暂时跳过OnButtonClicked方法的剩余部分。 OnButtonClicked方法退出并将控制权返回给操作系统。从Button的角度来看,事件处理程序已经完成。
当用户关闭警报框时,OnButtonClicked方法的其余部分将从为结果变量赋值布尔值开始继续执行。在某些情况下,可以在幕后进行一些优化。例如,如果异步操作立即完成,则执行流程可以正常继续。
await运算符还有另一个奖励:请注意,没有使用Device.BeginInvokeOnMainThead。当用户解除警报时,OnButtonClicked方法会自动在用户界面线程中恢复执行,这意味着它可以访问Label。 (在某些情况下,出于性能原因,您可能希望继续在后台线程中运行。如果是这样,您可以使用Task的ConfigureAwait方法来执行此操作。您将在本章后面看到一个示例。)
await关键字实质上将异步代码转换为看似正常的顺序命令代码的东西。当然,在幕后,这个程序与之前的两个程序之间并没有太大区别。在所有这三种情况下,OnButtonClicked处理程序在显示警报时将控制权返回给操作系统,并在警报解除时恢复执行。
仅出于说明的目的,三个程序在调用DisplayAlert方法后立即显示一些文本。如果没有必要,那么可以将DisplayAlert调用与await运算符组合以完全删除显式的Task 变量:

bool result = await DisplayAlert("Simple Alert", "Decide on an option",                                 "yes or ok", "no or cancel");

这就是await常见于代码中的方式。 DisplayAlert返回Task ,但是await运算符在后台任务完成后有效地提取bool结果。

实际上,您可以像使用任何其他运算符一样使用await,它可以出现在更复杂的表达式中。 例如,如果您不需要在DisplayAlert调用之后显示文本的语句,您实际上可以将await运算符和DisplayAlert放在最终的String.Format调用中:

async void OnButtonClicked(object sender, EventArgs args){    label.Text = String.Format("Alert {0} button was pressed",        await DisplayAlert("Simple Alert", "Decide on an option",                           "yes or ok", "no or cancel") ? "OK" : "Cancel");}

这可能有点难以阅读,但将await运算符和DisplayAlert方法的组合视为bool并且该语句非常有意义。

您可能已经注意到OnButtonClicked方法标有async关键字。 您使用await的任何方法都必须标记为async。 但是,async关键字不会更改方法的签名。 OnButtonClicked仍然有资格作为Clicked事件的事件处理程序。
但并非每种方法都可以是异步方法。

转载地址:http://mgnyl.baihongyu.com/

你可能感兴趣的文章
安装VirtualBox出错提示Unable to load R3 module ...VBoxDD.dll (VBoxDD):GetLastError=1790
查看>>
RHEL/CentOS 6.x 系统服务详解
查看>>
1085 a+b
查看>>
Oracle 数据操作
查看>>
形式与内容
查看>>
docker port 2376
查看>>
为什么你应该从现在起就写博文
查看>>
server2008实验之四 文件服务器配置磁盘配额和卷影副本
查看>>
linux中进程和计划任务的管理(二)命令补充
查看>>
一体台式机时代来了,传统PC该终结了
查看>>
[置顶] Java集群优化——dubbo+zookeeper构建高可用分布式集群
查看>>
史上最全体检表、检验报告解析
查看>>
UI设计师不可不知的安卓屏幕知识
查看>>
Linux 进程的三种状态
查看>>
inux上网
查看>>
Delphi XE2 之 FireMonkey 入门(8) - TImage
查看>>
心里烦 发泄一下
查看>>
Android adb工具
查看>>
WindowsServer 2008 AD搭建FTP隔离用户
查看>>
学点 C 语言(37): 函数 - 常量(const)参数
查看>>