问题
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"
回答1:
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)));
来源:https://stackoverflow.com/questions/16080355/how-to-update-gui-in-c-sharp-wpf-from-asynchronous-method-callback