回到網上
在本章之前,本書中唯一的異步代碼涉及使用可移植類庫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動畫實作。