C# WPF控件的扩展方法导致StackOverflowException
以下是我的扩展方法:C# WPF控件的扩展方法导致StackOverflowException,c#,wpf,extension-methods,C#,Wpf,Extension Methods,以下是我的扩展方法: public static void SetThreadSafeProperty<T>(this System.Windows.FrameworkElement control, Expression<Func<T>> property, T value) { if (control.Dispatcher.CheckAccess()) { var del = new SetThreadSafePropert
public static void SetThreadSafeProperty<T>(this System.Windows.FrameworkElement control, Expression<Func<T>> property, T value)
{
if (control.Dispatcher.CheckAccess())
{
var del = new SetThreadSafePropertyDelegate<T>(SetThreadSafeProperty);
control.Dispatcher.Invoke(del, control, property, value);
}
else
{
PropertyInfo propertyInfo = GetPropertyInfo(property);
if (propertyInfo != null)
{
propertyInfo.SetValue(control, value, null);
}
}
}
调试之后,它看起来像陷入了一个无限循环。CheckAcess()为true,它创建deletegate并正确调用。但它不断前进,最终失败了
你知道为什么会发生这种情况吗?你的情况不对-
CheckAccess()
在可以修改当前线程中的对象时,将返回true
目前,您会说,“如果我已经在UI线程中,请在UI线程中再次调用该方法”-这显然会导致问题。您想说“如果我不在UI线程中,请在UI线程中再次调用该方法”-因此您的代码应该是:
if (!control.Dispatcher.CheckAccess())
您的条件是错误的-
CheckAccess()
将在可以修改当前线程中的对象时返回true
目前,您会说,“如果我已经在UI线程中,请在UI线程中再次调用该方法”-这显然会导致问题。您想说“如果我不在UI线程中,请在UI线程中再次调用该方法”-因此您的代码应该是:
if (!control.Dispatcher.CheckAccess())
在调试器中使用断点运行它,看看问题是否变得明显。应该是相反的:
如果(!control.Dispatcher.CheckAccess())
@Clemens就是这样,谢谢!在调试器中使用断点运行它,看看问题是否变得明显。应该是相反的:如果(!control.Dispatcher.CheckAccess())
@Clemens就是这样,谢谢!啊,是的。我正在将WinForm库转换为WPF,InvokeRequired属性具有相反的效果。它起作用了。谢谢啊,是的。我正在将WinForm库转换为WPF,InvokeRequired属性具有相反的效果。它起作用了。谢谢