如何在C#中更新GUI的异步方法回调WPF回调、方法、如何在、WPF

2023-09-03 08:18:16 作者:一纸繁华、燃尽年华往事

我有搜索的计算器,并在网上和我找不到解决我的问题。

我从异步的方式流中读取。我想回调更新GUI

  [STAThread]
    私人无效ClientLoggedCallback(IAsyncResult的RES)
    {
        尝试
        {
            MailCli​​ent.Helpers.Client.getInstance()client.GetStream()EndWrite(RES)。
            。MailCli​​ent.Helpers.Client.getInstance()asyncRecieveEncryptedProtocolMessage(新的AsyncCallback(LoginInfo_recieved));
        }
        抓住 { }
    }
    [STAThread]
    私人无效LoginInfo_recieved(IAsyncResult的RES)
    {
        尝试
        {
            MailCli​​ent.Helpers.Client.getInstance()client.GetStream()EndRead(RES)。
            MailCli​​ent.AsyncState状态=(MailCli​​ent.AsyncState)res.AsyncState;
            串答案= Aes.DecryptStringFromBytes_Aes(state.buffer,state.AES_KEY,state.AES_IV);
            如果(answer.Contains(OK))
            {
                串[] answer_params = answer.Split(,);
                LoggedUserInfo.USER_ID = Convert.ToInt32(answer_params [1]);
                LoggedUserInfo.USER_LOGIN = answer_params [2];

                // zalogowano
                //this.TargetWindow =新MessageListsWindow();
                Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background,新的行动(()=> this.TargetWindow =新MessageListsWindow()));
                //System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,新的行动(()=> this.TargetWindow =新MessageListsWindow()));
            }
            其他
            {
                // ZLE戴恩
                System.Windows.MessageBox.Show(ZLE丹麦人);
            }
        }
        赶上(例外exep){}
    }
 

这是声明asyncSendEncryptedProtocolMessage的

  asyncSendEncryptedProtocolMessage(字符串消息,AsyncCallback的回调)
 

使用功能

  clientStream.BeginWrite(encryptedMessage,0,encryptedMessage.Length回调,ST);
 
java 中的异步回调方法

在code执行我得到异常调用线程必须STA,因为许多UI组件都需要这个。我读到SetApartmentState(ApartmentState.STA);但我不知道如何使用它回调。我也试着用STAThread属性,但它不工作。我使用MVVM轻框架。

堆栈跟踪

 W System.Windows.Threading.DispatcherObject.VerifyAccess(个)\ r \ NW System.Windows.Application.get_MainWindow(个)\ r \ NW MailCli​​ent.ViewModel.MainWindowModel.LoginInfo_recieved( IAsyncResult的RES)WC:\\ \\用户\\ OEM文件\\的Visual Studio 2012 \\ \\项目\\ MvvmLight3 \\的MailCli​​ent视图模型\\ MainWindowModel.cs:wiersz 171
 

解决方案

 公共静态无效的调度(此DispatcherObject源,动作FUNC)
    {
        如果(source.Dispatcher.CheckAccess())
            FUNC();
        其他
            source.Dispatcher.Invoke(FUNC);
    }
 

,然后用它是这样的:

  MailCli​​ent.Helpers.Client.getInstance()
.asyncRecieveEncryptedProtocolMessage(新的AsyncCallback(()=>
Application.Current.MainWindow.Dispatch(LoginInfo_recieved)));
 

I've search on stackoverflow and also in net and I couldn't find solution to my problem.

I read from a stream in async way. I want callback to update 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) { }
    }

This is declaration of asyncSendEncryptedProtocolMessage

asyncSendEncryptedProtocolMessage(string message, AsyncCallback callBack) 

use function

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

when code executes I get exception "The calling thread must be STA, because many UI components require this." I read about "SetApartmentState(ApartmentState.STA);" but I don't know how to apply it to callback. I've also tried with STAThread attribute but it doesn't work. I use MVVM Light framework.

StackTrace

" 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"

解决方案

 public static void Dispatch(this DispatcherObject source, Action func)
    {
        if (source.Dispatcher.CheckAccess())
            func();
        else
            source.Dispatcher.Invoke(func);
    }

And then use it like this:

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