Showing posts with label asynchronous. Show all posts
Showing posts with label asynchronous. Show all posts

Tuesday, November 22, 2016

C# Tip - Using the async and await keywords for asynchronous programming

In C#, you can use the async and await keywords for asynchronous programming (such as fetching data from a network, or saving/loading data from files). To understand how to use these 2 keywords, consider the following example:

    async Task DownloadFromWebAsync()
    {
        HttpClient client = new HttpClient();
        Task getStringAsyncTask = 
            client.GetStringAsync("http://www.google.com");
        string content = await getStringAsyncTask;         

        // control is returned to the caller 
        // of the DownloadFromWebAsync() method 
        // and resumed after getStringAsyncTask 
        // is completed    

        return content;
    } 

In the above DownloadFromWebAsync() method , it is first of all prefixed with the async keyword, which indicates that this method contains an asynchronous operation. This method returns a Task result. This represents an asynchronous operation that returns a result of type string:

    async Task DownloadFromWebAsync()

Within this method, we use the HttpClient class to help us connect to the Web:

        HttpClient client = new HttpClient();

In particular, the GetStringAsync() method connects to the specified URL and returns the content of the URL. It returns an object of type Task:

        Task getStringAsyncTask = 
            client.GetStringAsync("http://www.google.com");

Because the GetStringAsync() method could potentially take a long time, and so you need to run it asynchronously. This is achieved by using the await keyword:

        string content = await getStringAsyncTask;

At this point, the GetStringAsync() method will proceed to download the specified URL and control will return to the caller of the DownloadFromWebAsync() method. All statements after this line will only be executed after the GetStringAsync() method returns.

When the GetStringAsync() method returns, the result is passed to content, and the DownloadFromWebAsync() method will now return a string.

To call the DownloadFromWebAsync() method, you would need to use the await keyword. Also, the method from which you are calling the DownloadFromWebAsync() method must also be prefixed with the async keyword, like this:

    private async void button1_Click(object sender, EventArgs e)
    {
        string content = await DownloadFromWebAsync();
    }

Note that the 2 statements:

    Task getStringAsyncTask = 
        client.GetStringAsync("http://www.google.com");
    string content = await getStringAsyncTask;         

Can also be rewritten as:

    string content = await      
        client.GetStringAsync("http://www.google.com");

I hope this simple example makes it easier for you to understand how to use the async and await keywords.

Friday, July 12, 2013

Windows Phone Tip: Updating the UI from an Asynchronous Thread

One of the most common tasks you need to perform in a Windows Phone application is updating the UI from a separate thread. For example, you may be download some content asynchronously using a WebClient class and when the operation is completed, you want to update the UI with the content that was downloaded. Updating the UI directly from an asynchronous thread is not allowed, as UI controls are not thread-safe.  

The easiest way to update the UI from an asynchronous thread is to use the Dispatcher class. To determine if you can update an UI directly, you can use the CheckAccess() method. If this method returns a true, it means you can directly update the UI. Else, you have to use the BeginInvoke() method of the Dispatcher class to update the UI in a thread-safe manner. The following code snippet makes this clear:

    if (Dispatcher.CheckAccess() == false)
    {
        //---you have to update the UI through the
        // BeginInvoke() method---
        Dispatcher.BeginInvoke(() =>
            txtStatus.Text = "Something happened..."
        );
    }
    else
    {
        //---you can update the UI directly---
        txtStatus.Text = "Something happened..."
    }

If you have more than one statement to perform in the BeginInvoke() method, you can group them into a method and call it like this:


        private void UpdateUI(String text)
        {
            txtStatus.Text = text;
            btnLogin.Content = text;
        }
        ...
        ...

            Dispatcher.BeginInvoke(() =>
                UpdateUI("Something happened...")

            );