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; 因为调用打开一个新线程,我该如何修复它?错误是:
该应用程序调用了为不同线程编组的接口。
答案 0 :(得分: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控件的属性。
答案 1 :(得分: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;
[...]