我已经了解了我遇到的这个问题,我似乎无法找到解决方案。有些人建议使用调度程序将代码执行推送到UI线程。但这并不能解决我的问题。我从Asyc方法调用此代码,该方法由Guide对象调用,以显示通知。控制UI内容的代码如下:
public bool isDisabled
{
set
{
if (value)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
color = new SolidColorBrush(Colors.Gray);
});
enabled = false;
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
color = origionalColor;
});
enabled = true;
}
}
}
正在从
调用它 private void nameInputFinished(IAsyncResult ar)
{
int? result = Guide.EndShowMessageBox(ar);
if (result == 0)
{
[...]
JourneyPanels.getPanel(JourneyPanelTypes.integration).isDisabled = false;
}
}
不确定为什么我得到了corss-thread异常,但我很确定它与async方法嵌套有关。
非常感谢任何帮助!
编辑:完全异常堆栈
{System.UnauthorizedAccessException: Invalid cross-thread access.
at MS.Internal.XcpImports.CheckThread()
at MS.Internal.XcpImports.SetValue(IManagedPeerBase obj, DependencyProperty property, Boolean b)
at System.Windows.DependencyObject.SetValue(DependencyProperty property, Boolean b)
at System.Windows.Controls.TextBox.set_IsReadOnly(Boolean value)
at PocketRitual.Journey.nameInputFinished(IAsyncResult ar)
at Microsoft.Xna.Framework.GamerServices.ActionDialogHelper.Complete()
at Microsoft.Xna.Framework.GamerServices.ActionDialogHelper.GetMessageBoxResult(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()}
答案 0 :(得分:4)
这是您需要在主UI线程上运行的调用代码,例如。
Deployment.Current.Dispatcher.BeginInvoke(() => {
JourneyPanels.getPanel(JourneyPanelTypes.integration).isDisabled = false;
});
您无需在内部属性更改上调用Dispatcher
,因为此时您将在UI线程上运行。
答案 1 :(得分:1)
您没有包含完整的代码,让人们猜测。我非常怀疑isDisabled(BTW,在.NET世界中我们用大写字母命名属性)例如只有一个setter。我还打赌这用于数据绑定,因此setter有额外的代码来引发PropertyChanged事件。最好的猜测是在后台线程而不是UI线程上引发了PropertyChanged事件。设计明智,最好不要隐藏在酒店内。当你不在后台线程中时,它会增加不必要的开销。当后台线程执行任何会影响UI的操作时,包括更改数据绑定的属性,应该通过后台线程中的调度程序调用该操作。