第二十章:異步和文件I/O.(二十三)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章