例外:应用程序调用被编组为一个不同的线程的接口 [英] Exception: The application called an interface that was marshalled for a different thread

查看:124
本文介绍了例外:应用程序调用被编组为一个不同的线程的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 的,并得到符合这个错误的进度.IsIndeterminate = FALSE; 的因为调用打开一个新的线程,我怎么能解决这个问题?错误的是:

api.AutenticarUsuario(); calls a rest API asynchronously, when it's done it calls the event handler api.AutenticarUsuarioFinalizado and got this error in line ProgressBar.IsIndeterminate = false; because the call open a new thread, how can I fix it? the error is:

应用程序调用被编组为不同的线程的接口。

推荐答案

的问题是,你的事件处理程序没有在UI线程上执行。我认为解决这个问题的最好办法是将您的EAP(基于事件的异步模式)方法转换为使用为TAP(基于任务的异步模式) TaskCompletionSource

The problem is that your event handler doesn't execute on the UI thread. I think the best way to fix that is to convert your EAP (Event-based Asynchronous Pattern) method to TAP (Task-based Asynchronous Pattern) using TaskCompletionSource:

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;
    }
}

由于等待 ING一个工作将始终在原有范围内继续,你不会得到一个除了这个样子。作为一个额外的好处,你不用写你的code由内向外,就像你做EAP

Because awaiting a Task will always resume on the original context, you're not going to get an exception this way. As an additional advantage, you don't have to write your code "inside-out", like you do with EAP.

您也应该考虑使用绑定,而非手动设置你的UI控件的属性。

You should also consider using bindings, instead of setting the properties of your UI controls manually.

这篇关于例外:应用程序调用被编组为一个不同的线程的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆