Asynchrone Programmierung in .NET 4.5 mit async und await

Seite 5: Listing 1

Inhaltsverzeichnis
using System.Data;
using System.Data.SqlClient;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace WPF45
{
/// <summary>
/// Interaction logic for WPFDataAccessAsync.xaml
/// </summary>
public partial class WPFDataAccessAsync : Window
{
public WPFDataAccessAsync()
{
this.DataContext = this;
InitializeComponent();
}


/// <summary>
/// Dependency Property für Datenbindung an TextBlock C_Status
/// </summary>
public string Status
{
get { return (string)GetValue(StatusProperty); }
set { SetValue(StatusProperty, value); }
}
public static DependencyProperty StatusProperty =
DependencyProperty.Register("Status", typeof(string),
typeof(WPFDataAccessAsync), null);

/// <summary>
/// Verwaltungsobjekt für Abbruch der Aktion
/// </summary>
private CancellationTokenSource cts = null;

private async void C_Laden_Click(object sender, RoutedEventArgs e)
{
cts = new CancellationTokenSource();

Print("C_Laden_Click() #1: Aufruf wird initiiert.");
ReadDataAsync(cts.Token);

Print("C_Laden_Click() #2: Aufruf ist erfolgt.");
}

private void C_Abbrechen_Click(object sender, RoutedEventArgs e)
{
Print("Abbruch des Ladens wird eingeleitet...");
cts.Cancel();
Print("Laden ist abgebrochen!");
}

private void C_Ende_Click(object sender, RoutedEventArgs e)
{
this.Close();
}

/// <summary>
/// Asynchroner Datenzugriff
/// Hinweis: Natürlich gehört Datenzugriffscode normalerweise nicht
/// in die Code-Behind-Datei. Aber hier soll es nur darum gehen, auf
/// übersichtliche Weise das TA-Pattern zu erklären
/// </summary>
private async Task<bool> ReadDataAsync(CancellationToken ct)
{
Status = "";
Print("Beginn ReadDataAsync");
// Datenbankverbindung asynchron aufbauen
var conn =
new SqlConnection(
@"data source=.;initial catalog=WWWings6;integrated security=True;
MultipleActiveResultSets=True;App=ADONETClassic");
await conn.OpenAsync(ct);
Print("Nach OpenAsync");
// Daten asynchron abrufen
var cmd = new SqlCommand("select * from flug", conn);
var reader = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection,
ct);
Print("Nach ExecuteReaderAsync");

// Nur zum Test: Ausführungszeit künstlich verlängern, wenn die
// Datenbankabfrage zu schnell ist
for (int i = 0; i < 100; i++)
{
await Task.Delay(50);
if (ct.IsCancellationRequested)
{
Print("Laden wird abgebrochen!");
return false;
}
}

// Verpacken in DataTable zur Datenbindung an GridView
DataTable dt = new DataTable();
dt.Load(reader);
C_Daten.ItemsSource = dt.DefaultView;

// Verbindung beenden
conn.Close();
Print("Ende ReadDataAsync");
return true;
}

private void Print(string s)
{
int tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
string ausgabe = s + " Thread=" + tid;
Status += ausgabe + "\n";
System.Diagnostics.Debug.WriteLine(ausgabe);
}

}
}