2013-06-21 28 views
2
private void LogInButton_Click(object sender, RoutedEventArgs e) 
{ 
    var api = new RestAPI("http://localhost:2624/", UsernameTextBox.Text, PasswordTextBox.Password); 

    api.AutenticarUsuarioFinalizado += (o, args) => 
    { 
     ProgressBar.IsIndeterminate = false; 
     ProgressBar.Visibility = Visibility.Collapsed; 
     LogInButton.IsEnabled = true; 

     if (args.Error) return; 

     if (args.Resultado.Autenticado) 
     { 
     } 
    }; 

    api.AutenticarUsuario(); 
    ProgressBar.Visibility = Visibility.Visible; 
    ProgressBar.IsIndeterminate = true; 
    LogInButton.IsEnabled = false; 
} 

api.AutenticarUsuario();異步調用rest API,當它完成時它調用事件處理程序api.AutenticarUsuarioFinalizado並在行中得到了此錯誤ProgressBar.IsIndeterminate = false;因爲打開一個新的線程,我該如何解決它?錯誤是:例外:該應用程序稱爲被編組爲不同線程的接口

該應用程序稱爲一個接口被編組爲一個不同的線程。

回答

4

的問題是,你的事件處理程序不會在UI線程上執行。我認爲解決這個問題的最好辦法是使用TaskCompletionSource到您的EAP(基於事件的異步模式)方法轉換爲TAP(基於任務的異步模式):

public static Task<Resultado> AutenticarUsuarioAsync(this RestAPI api) 
{ 
    var tcs = new TaskCompletionSource<Resultado>(); 

    api.AutenticarUsuarioFinalizado += (sender, args) => 
    { 
     if (args.Error) 
      tcs.TrySetException(new SomeAppropriateException()); 
     else 
      tcs.TrySetResult(args.Resultado); 
    }; 

    api.AutenticarUsuario(); 

    return tcs.Task; 
} 

… 

private async void LogInButton_Click(object sender, RoutedEventArgs e) 
{ 
    var api = new RestAPI(
     "http://localhost:2624/", UsernameTextBox.Text, 
     PasswordTextBox.Password); 

    ProgressBar.Visibility = Visibility.Visible; 
    ProgressBar.IsIndeterminate = true; 
    LogInButton.IsEnabled = false; 

    try 
    { 
     var resultado = await api.AutenticarUsuarioAsync(); 
     if (resultado.Autenticado) 
     { 
      // whatever 
     } 
    } 
    catch (SomeAppropriateException ex) 
    { 
     // handle the exception here 
    } 
    finally 
    { 
     ProgressBar.IsIndeterminate = false; 
     ProgressBar.Visibility = Visibility.Collapsed; 
     LogInButton.IsEnabled = true; 
    } 
} 

因爲await荷蘭國際集團一Task總是會在恢復原始上下文,你不會以這種方式得到異常。作爲一個額外的優勢,您不必像「EAP」那樣「內外」編寫代碼。

您還應該考慮使用綁定,而不是手動設置UI控件的屬性。

+0

這是一個快速原型,這就是爲什麼我沒有使用綁定,但我會:)謝謝 – Geykel

3

您的AutenticarUsuarioFinalizado事件處理程序可能正在與UI線程不同的線程中執行。您應該只從UI線程修改/創建UI對象。使用在事件處理調度程序,點擊這裏:Run code on UI thread in WinRT

var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher; 
api.AutenticarUsuarioFinalizado += (o, args) => 
{ 
    dispatcher.RunAsync(DispatcherPriority.Normal,() => 
     ProgressBar.IsIndeterminate = false; 
     ProgressBar.Visibility = Visibility.Collapsed; 
    [...] 
相關問題