2014-11-21 19 views
-1

我有一個在WinForms中工作的擴展,我試圖讓它在WPF中工作,但當ic全部爲.Compile()。DynamicInvoke()時拋出以下異常。調用編譯()。擴展方法中的DynamicInvoke會導致WPF中的「調用的目標」錯誤,但不是WinForms

Error Screenshot

這裏是我如何調用該方法:

spDetailControls.InvokeThreadSafeMethod(() => spDetailControls.Children.Add(_generalDetail)); 

這裏是擴展方法:

public static void InvokeThreadSafeMethod(this System.Windows.FrameworkElement control, Expression<Action> method) 
{ 
    if (!control.Dispatcher.CheckAccess()) 
    { 
     var del = new InvokeThreadSafeMethodDelegate(InvokeThreadSafeMethod); 
     control.Dispatcher.Invoke(del, control, method); 
    } 
    else 
    { 
     method.Compile().DynamicInvoke(); 
    } 
} 

有別的我應該在WPF被調用?還是我失蹤的其他東西?

編輯:

每LucasTrzesniewski的建議下,我改變了表達的只是行動。它不再拋出該錯誤,而是拋出一個交叉線程異常錯誤。這個擴展方法的全部意義在於它可以在後臺線程中調用。

以下是更改後的代碼。這可能是因爲我改變了一些錯誤

public static void InvokeThreadSafeMethod(this System.Windows.FrameworkElement control, Action method) 
{ 
    if (!control.Dispatcher.CheckAccess()) 
     control.Dispatcher.Invoke(new InvokeThreadSafeMethodDelegate(InvokeThreadSafeMethod), control, method); 
    else 
     method.DynamicInvoke(); 
} 

我不得不改變代表,以及:

private delegate void InvokeThreadSafeMethodDelegate(System.Windows.FrameworkElement control, Action method); 
+3

爲什麼用'Expression '而不是'Action'?看起來像不正確(無用)使用表達式樹。 – 2014-11-21 12:46:17

+0

@LucasTrzesniewski該代碼最初並不是爲WPF設計的。我將把它改爲Action,看看會發生什麼。謝謝! – ernest 2014-11-21 12:53:23

+0

我沒有看到'method'在這裏如何訪問'control',所以跨線程異常可能意味着有一些其他的控件在'method'被調用時被實際訪問,請顯示調用'InvokeThreadSafeMethod '(顯然需要'Action'的1個參數)。 – 2014-11-21 13:15:39

回答

1

您的擴展方法過於複雜,並可能被混淆原產於您的委託錯誤。這就是你需要:

public static void InvokeThreadSafeMethod(
    this System.Windows.FrameworkElement control, 
    Action method) 
{ 
    if (control.Dispatcher.CheckAccess()) 
     method(); 
    else 
     control.Dispatcher.Invoke(method); 
} 

如果您在使用上面的實現,那麼你的委託可能觸及這是在不同的線程創建比control UI元素得到一個跨線程異常。

例如,如果這是你的實際代碼:

spDetailControls.InvokeThreadSafeMethod(
    () => spDetailControls.Children.Add(_generalDetail)); 

...那麼也許你_generalDetail在後臺線程?

+0

與此確切代碼發生相同的交叉線程錯誤:調用線程不能訪問此對象,因爲不同的線程擁有它。 – ernest 2014-11-21 13:33:08

+1

然後,其他事情正在發生。我們需要查看確切的堆棧跟蹤,以及所有內部異常和堆棧跟蹤。另外,你能告訴我們用這種方法執行哪個代碼嗎?如果這是您原始文章中的示例,您是否在後臺線程上創建了_generalDetail?如果是這樣,那就是你的問題。 – 2014-11-21 13:58:13

+0

這絕對是一個spDetailControls的問題,它是主UI上的堆棧面板。 _generalDetail是一個被添加到StackPanel的控件。它也在UI線程上。但是,如果_generalDetail在後臺線程中聲明,錯誤仍然會發生。我正在嘗試收集更多調試數據。 – ernest 2014-11-21 14:23:30

相關問題