【问题标题】:How to update gui in c# wpf from asynchronous method callback如何从异步方法回调更新c#wpf中的gui
【发布时间】:2013-04-18 10:22:03
【问题描述】:

我在 stackoverflow 和网络上都进行了搜索,但找不到解决问题的方法。

我以异步方式从流中读取数据。我想要回调来更新 gui

[STAThread]
    private void ClientLoggedCallback(IAsyncResult res)
    {
        try
        {
            MailClient.Helpers.Client.getInstance().client.GetStream().EndWrite(res);
            MailClient.Helpers.Client.getInstance().asyncRecieveEncryptedProtocolMessage(new AsyncCallback(LoginInfo_recieved));
        }
        catch { }
    }
    [STAThread]
    private void LoginInfo_recieved(IAsyncResult res)
    {
        try
        {
            MailClient.Helpers.Client.getInstance().client.GetStream().EndRead(res);
            MailClient.AsyncState state = (MailClient.AsyncState)res.AsyncState;
            string answer = Aes.DecryptStringFromBytes_Aes(state.buffer, state.AES_KEY, state.AES_IV);
            if (answer.Contains("OK"))
            {
                string[] answer_params = answer.Split(',');
                LoggedUserInfo.USER_ID = Convert.ToInt32(answer_params[1]);
                LoggedUserInfo.USER_LOGIN = answer_params[2];

                //zalogowano
                //this.TargetWindow = new MessageListsWindow();
                Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new Action(() => this.TargetWindow = new MessageListsWindow()));
                //System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,  new Action(() => this.TargetWindow = new MessageListsWindow()));
            }
            else
            {
                //zle dane
                System.Windows.MessageBox.Show("Zle dane");
            }
        }
        catch(Exception exep) { }
    }

这是 asyncSendEncryptedProtocolMessage 的声明

asyncSendEncryptedProtocolMessage(string message, AsyncCallback callBack) 

使用功能

clientStream.BeginWrite(encryptedMessage, 0, encryptedMessage.Length, callBack, st);

当代码执行时,我得到异常“调用线程必须是 STA,因为许多 UI 组件都需要这个。”我读到“SetApartmentState(ApartmentState.STA);”但我不知道如何将其应用于回调。我也尝试过使用 STAThread 属性,但它不起作用。我使用 MVVM Light 框架。

堆栈跟踪

" w System.Windows.Threading.DispatcherObject.VerifyAccess()\r\n   w System.Windows.Application.get_MainWindow()\r\n   w MailClient.ViewModel.MainWindowModel.LoginInfo_recieved(IAsyncResult res) w c:\\Users\\oem\\Documents\\Visual Studio 2012\\Projects\\MvvmLight3\\MailClient\\ViewModel\\MainWindowModel.cs:wiersz 171"

【问题讨论】:

  • 你是什么堆栈跟踪?它不是指向 MessageBox.Show 调用吗?
  • 我不关注MessageBox,可能它会给出同样的错误。我将使用 stacktrace 进行编辑。

标签: c# .net wpf asynchronous mvvm-light


【解决方案1】:
 public static void Dispatch(this DispatcherObject source, Action func)
    {
        if (source.Dispatcher.CheckAccess())
            func();
        else
            source.Dispatcher.Invoke(func);
    }

然后像这样使用它:

MailClient.Helpers.Client.getInstance()
.asyncRecieveEncryptedProtocolMessage(new AsyncCallback(()=> 
Application.Current.MainWindow.Dispatch(LoginInfo_recieved)));

【讨论】:

  • 我应该把这个 Dispatch() 方法放在哪里?
  • 在任何publis静态类中,都是扩展方法。
  • 此代码已磨损委托 AsyncCallback 有 1 个参数,当我将其更改为 MailClient.Helpers.Client.getInstance().asyncRecieveEncryptedProtocolMessage(new AsyncCallback((a) => System.Windows.Application .Current.MainWindow.Dispatch(LoginInfo_recieved)));它也不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
相关资源
最近更新 更多