回到网上
在本章之前,本书中唯一的异步代码涉及使用可移植类库WebRequest中唯一可用于此目的的合理类进行Web访问。 WebRequest类使用称为异步编程模型或APM的旧异步协议。 APM涉及两种方法,在WebRequest的情况下,这些方法称为BeginGetResponse和EndGetResponse。
您可以使用TaskFactory的FromAsync方法将这对方法调用转换为基于任务的异步模式(TAP),ApmToTap程序演示如何。 该程序使用Web访问和ImageSource.FromStream加载位图并显示它。 这种技术在第13章中作为ImageSource.FromUri的替代方法展示。
XAML文件包含一个等待位图的Image元素,一个在加载位图时运行的ActivityIndicator,一个显示可能错误消息的Label,以及一个用于开始下载的Button:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ApmToTap.ApmToTapPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<StackLayout>
<Grid VerticalOptions="FillAndExpand">
<Label x:Name="errorLabel"
HorizontalOptions="Center"
VerticalOptions="Center" />
<ActivityIndicator IsRunning="{Binding Source={x:Reference image},
Path=IsLoading}" />
<Image x:Name="image" />
</Grid>
<Button Text="Load Bitmap"
HorizontalOptions="Center"
Clicked="OnLoadButtonClicked" />
</StackLayout>
</ContentPage>
代码隐藏文件将所有WebRequest代码合并到名为GetStreamAsync的异步方法中。 在实例化TaskFactory和WebRequest对象之后,该方法将BeginGetResponse和EndGetResponse方法传递给TaskFactory的FromAsync方法,该方法然后返回一个可用的Stream的WebResponse对象:
public partial class ApmToTapPage : ContentPage
{
public ApmToTapPage()
{
InitializeComponent();
}
async void OnLoadButtonClicked(object sender, EventArgs args)
{
try
{
Stream stream =
await GetStreamAsync("https://developer.xamarin.com/demo/IMG_1996.JPG");
image.Source = ImageSource.FromStream(() => stream);
}
catch (Exception exc)
{
errorLabel.Text = exc.Message;
}
}
async Task<Stream> GetStreamAsync(string uri)
{
TaskFactory factory = new TaskFactory();
WebRequest request = WebRequest.Create(uri);
WebResponse response = await factory.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null);
return response.GetResponseStream();
}
}
然后,Button的Clicked处理程序可以通过使用URI调用GetStreamAsync来获取该Stream对象。 像往常一样,带有await运算符的代码位于try块中以捕获任何可能的错误。 你可以通过故意拼写错误的域名或文件名进行实验,看看你得到了什么样的错误。
Web访问的另一个选项是System.Net.Http命名空间中名为HttpClient的类。 在Xamarin.Forms解决方案中,可移植类库中包含的.NET版本中没有此类,但Microsoft已将该类作为NuGet包提供:
https://www.nuget.org/packages/Microsoft.Net.Http
从Visual Studio或Xamarin Studio中的NuGet管理器,只需搜索“HttpClient”。
HttpClient基于TAP。 异步方法返回Task和Task 对象,某些方法也有CancellationToken参数。
然而,这些方法都没有报告进展,这表明便携式类库仍然无法使用一流的现代Web访问类。
在下一章中,您将看到更多用于等待和探索基于任务的异步模式的一些其他功能,以及令人兴奋的Xamarin.Forms动画实现。