В прошлом году я написал библиотеку веб-API с классическими синхронными и асинхронными методами.Сейчас я пытаюсь добавить методы TaskAsync, используя новый C # Async CTP 3 .
Я написал этот простой код для инкапсуляции метода синхронизации:
partial class Client : IClient {
public string Authenticate(string username, string password)
{
// long synchronous code here
}
public Task<string> AuthenticateTaskAsync(string username, string password) {
var p = new { username = username, password = password };
var task = new Task<string>(p1 => this.Authenticate(p.username, p.password), p);
return task;
}
}
Затем из моего приложения WPF 4 у меня есть асинхронный метод, использующий его:
public class LoginViewModel {
private IClient client;
// called by an ICommand
private async Task DoLogin(string username, string password) {
UpdateStatus("Authenticating...", true);
try {
var result = await client.AuthenticateTaskAsync(username, password);
// do stuff with result
UpdateStatus("Authenticated. Fetching User informations...", true);
} catch (Exception ex) {
UpdateStatus("Authentication error.", ex, false);
}
}
}
Проблема в том, что мой синхронный метод никогда не вызывается. Отладчик переходит на result = await client.AuthenticateTaskAsync(username, password);
, отладчик продолжает свою работу и никогда не возвращается.Точка останова в пределах синхронизации Authenticate
никогда не прерывается.UpdateStatus
никогда не вызывается.Довольно странно (хотя это была проблема с реализацией отладчика).
Затем я посмотрел, как реализовано WebClient.DownloadStringTaskAsync
.Я изменил свой метод API-клиента следующим образом:
partial class Client : IClient {
public Task<string> AuthenticateTaskAsync(string username, string password) {
var tcs = new TaskCompletionSource<string>();
try {
tcs.TrySetResult(this.Authenticate(username, password));
} catch (Exception ex) {
tcs.TrySetException(ex);
}
return tcs.Task;
}
}
И теперь он работает.Может кто-нибудь объяснить, почему первый код не работает?