我以为我知道是什么导致了这个异常,直到我写了这篇文章:
var menu = ViewConfigHelper.CreateObjectFromResource<Menu>(config, baseURI);
if (!menu.Dispatcher.CheckAccess())
{
throw new ArgumentException("Somethign wrong");
}
if (!LayoutRoot.Dispatcher.CheckAccess())
{
throw new ArgumentException("SOmethign wrong");
}
// exception throw here
LayoutRoot.Children.Insert(0, menu);第一行从嵌入的XAML文件创建菜单控件。两个CheckAccess调用都返回true。但是,在执行最后一行时,会抛出一个异常,其中包含"Caling线程无法访问对象,因为不同线程拥有对象“。我相信,上面的代码是在创建InitializeComponent()之后立即调用的一个方法内执行的,该方法创建了同一个线程。
谁来指点我。我正在尝试创建一个多UI线程WPF应用程序。
发布于 2011-07-02 05:03:32
您正在相反地使用CheckAccess()。你想输掉!每次检查前都要签名。请参阅CheckAccess() MSDN页面上的代码示例。
在Winforms世界中,您将执行一个InvokeRequired(),这与!CheckAccess()是一样的。在您的情况下,因为这两个值都返回true,并且您正在反转它们,如果两个块都被击中,则两者都不会。
来扩展一点..。在Winforms世界中,正常的模式是:
if(InvokeRequired)
{
Invoke(...);
}
else
{
//do work
}(如果调用的方法相同,则有时在调用后返回)。
在WPF中,CheckAccess()与InvokeRequired相似,但不完全相同.有一种模式更符合以下几点:
if (someUiControl.Dispatcher.CheckAccess())
{
//Doing an update from this thread is safe, so we can do so here.
}
else
{
// This thread does not have access to the UI thread.
// Call the update thread via a Dispatcher.BeginInvoke() call.
}两者的主要区别在于,InvokeRequired()返回true意味着在当前线程中执行更新是不安全的.虽然CheckAccess()中的true表示它是安全的。
https://stackoverflow.com/questions/6555206
复制相似问题