Asynchronous and file I/O.

Posted by todd2006 on Mon, 20 May 2019 01:09:07 +0200

Back to the Internet
Before this chapter, the only asynchronous code in the book involved Web access using the only reasonable class in the portable class library WebRequest that could be used for this purpose. The WebRequest class uses an old asynchronous protocol called an asynchronous programming model or APM. APM involves two methods, called BeginGetResponse and EndGetResponse in the case of WebRequest.
You can use TaskFactory's FromAsync method to convert this pair of method calls into task-based asynchronous mode (TAP), and the ApmToTap program demonstrates how. The program uses Web access and ImageSource.FromStream to load the bitmap and display it. This technique is shown in Chapter 13 as an alternative to ImageSource.FromUri.
The XAML file contains an Image element waiting for the bitmap, an Activity Indicator running when loading the bitmap, a Label displaying a possible error message, and a Button for starting the download:

<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>

Code hiding files merge all WebRequest code into an asynchronous method called GetStreamAsync. After instantiating the TaskFactory and WebRequest objects, this method passes the BeginGetResponse and EndGetResponse methods to TaskFactory's FromAsync method, which then returns a Web Response object of a available Stream:

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's Clicked handler can then retrieve the Stream object by calling GetStream Async using the URI. As usual, code with await operators is located in try blocks to catch any possible errors. You can experiment with deliberately misspelled domain names or filenames to see what mistakes you get.
Another option for Web access is a class named HttpClient in the System.Net.Http namespace. In the Xamarin.Forms solution, there is no such class in the. NET version included in the portable class library, but Microsoft has provided this class as a NuGet package:
https://www.nuget.org/packages/Microsoft.Net.Http
From the NuGet manager in Visual Studio or Xamarin Studio, you only need to search for "HttpClient".
HttpClient is based on TAP. Asynchronous methods return Task and Task objects, and some methods also have CancellationToken parameters.
However, none of these methods reported progress, indicating that portable libraries still cannot use first-class modern Web access classes.
In the next chapter, you'll see more other features for waiting and exploring task-based asynchronous patterns, as well as exciting Xamarin.Forms animation implementations.

Topics: iOS Programming