Jens Willmer

Tutorials, projects, dissertations and more..

Async and await in .NET 4.5

Yesterday I was playing around with Windows 8 and VisualStudio 11 and because my University is developing a web service to connect to the class schedule I played around with the semi-finished service and tried to get some data out.

The implementation of the alpha service is horrible, there is no authorisation and there isn´t planed some, everyone can get the usernames of the students and their class schedules. Also there is no limitation of the output, I had to limit the output myself to avoid a crashing program while my integer was too small. Finally you can´t get a person by his unique mail address, you have to search for the last name and let the user select the right person because the mail is not provided and finally the search results are redundant.

So in short terms, the service is buggy but that´s not the problem, that´s a challenge ;-) Anyway my intension was to play around with the .NET-Framework 4.5 and the service was just an opportunity.

I used async and await the first time and I really liked it :-) It is very easy to use, with async in the header you can define your method as asynchronous and with the use of await you can select a specific function inside the asynchronous method that it needs to wait for. No need for callbacks anymore ;-) A very good article about async, await and the pros and contras can be found at msdn (german).

Below you can see my WPF solution. I can´t post the whole project because the service shouldn´t be available for everyone right now and it isn´t - there are some more hints needed to get it to work properly..

The only two methods I implemented (the service was implemented via service reference in VisualStudio):

private async void TextBoxUsername_TextChanged(object sender, TextChangedEventArgs e)
{
    DataGridUsernames.ItemsSource = null;
    DataGridCourse.ItemsSource = null;

	// min req length
    if (TextBoxUsername.GetLineLength(0) > 2)
        using (Service1Client client = new Service1Client())
        {
            try
            {
				// because the service defines no max output
                ((HttpBindingBase)(client.Endpoint.Binding)).MaxReceivedMessageSize = Int32.MaxValue;

                var users = await client.getUsersAsync(TextBoxUsername.Text);
                DataGridUsernames.ItemsSource = from user in users select new { user.firstName, user.lastName, user.userId };
            }
            catch (EndpointNotFoundException)
            {
                MessageBox.Show("Service unavailable!", "Info", MessageBoxButton.OK);
            }
            catch
            {
                MessageBox.Show("Undefined Error!", "Error", MessageBoxButton.OK);
            }
        }
}

private async void DataGridUsers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (DataGridUsernames.SelectedItem != null)
        try
        {
            using (Service1Client client = new Service1Client())
            {
                TimetabelListType[] courses = await client.getMyTimeTableForDayAsync(DateTimePicker.DisplayDate,
																((dynamic)DataGridUsernames.SelectedItem).userId);
                DataGridCourse.ItemsSource = null;
                DataGridCourse.ItemsSource = from course in courses select new { course.title,
																				 course.instructor,
																				 course.startDate,
																				 course.endDate };
            }
        }
        catch (EndpointNotFoundException)
        {
            MessageBox.Show("Service unavailable!", "Info", MessageBoxButton.OK);
        }
        catch
        {
            MessageBox.Show("Undefined Error!", "Error", MessageBoxButton.OK);
        }
}

And finally a pictue of the GUI (sorry for the noise): GUI of the app

Edit: A frind asked me for the XAML - see below ;-)

<Window x:Class="WSDL-______.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="______ Querry" Icon="favicon.ico"
		Height="340" MinHeight="340"
		Width="550" MinWidth="550">
    <DockPanel LastChildFill="True" >
        <Grid DockPanel.Dock="Top" VerticalAlignment="Bottom" Margin="5,10,5,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Content="Username"/>
            <TextBox Grid.Column="1" Name="TextBoxUsername" TextWrapping="Wrap" TextChanged="TextBoxUsername_TextChanged"/>
            <DatePicker Grid.Column="2" Name="DateTimePicker" BorderThickness="0" Margin="15,0,0,0"/>
        </Grid>
        <Grid DockPanel.Dock="Bottom" Margin="5,10,5,5">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition MinHeight="90" Height="*" />
                <RowDefinition Height="Auto" />
                <RowDefinition MinHeight="90" Height="*" />
            </Grid.RowDefinitions>
            <Label Grid.Row="0" Content="Anwender auswählen:"/>
            <DataGrid Grid.Row="1" Name="DataGridUsernames" SelectionChanged="DataGridUsers_SelectionChanged" IsReadOnly="True"/>
            <Label Grid.Row="2" Content="Kursübersicht"/>
            <DataGrid Grid.Row="3" Name="DataGridCourse" />
        </Grid>
    </DockPanel>
</Window>