2012-11-20 25 views
1

根據我們的要求,我們必須在新的UI線程中打開WPF窗口。調用線程無法訪問此對象,因爲在wpf窗口中使用動畫時,不同的線程擁有它

我們正處在一個新的UI線程使用下面的代碼的主UI線程打開的窗口:

Thread winthread = new Thread(new ThreadStart(() => 
{ 
    SynchronizationContext.SetSynchronizationContext(
     new DispatcherSynchronizationContext(
      Dispatcher.CurrentDispatcher)); 
    Window windowObj = new Window(); 
    Grid gridObj = new Grid(); 
    MyUserControl ctrl = new MyUserControl(); 
    gridObj.Children.Add(ctrl); 
    windowObj.Content = gridObj; 

    windowObj.Show(); 
    System.Windows.Threading.Dispatcher.Run(); 
})); 

winthread.IsBackground = true; 
winthread.SetApartmentState(ApartmentState.STA); 
winthread.Start(); 

的窗口將MyUserControl顯示爲內容上面的代碼執行時。 我正在做一些動畫,如翻轉我的用戶控件鼠標雙擊事件。

當我雙擊它的應用程序開始拋出以下異常:

,因爲不同的線程擁有它調用線程不能訪問該對象。

on line System.Windows.Threading.Dispatcher.Run()

任何人都可以建議解決這個問題?

+0

不好意思,這是因爲線程無法訪問對象,因爲不同的線程擁有它。哪一點你不完全理解,也許我們可以幫忙? –

+1

http:// stackoverflow。com/questions/9560068/the-calling-thread-can-access-this-object – Karthik

+0

@ Kieren Johnstone: - 爲了使它更清楚,我的動畫應該在邏輯上完美工作,因爲它運行在窗口所在的同一線程上創建,它不應該拋出任何異常。 –

回答

-1

聽起來像一個調用問題:

比較容易解決的,因爲你試圖改變網格/窗口在不同的線程。

更改線程調用一個變化

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/360540eb-d756-4434-86f9-a3449f05eb55

+0

感謝Rikoshay提出寶貴的建議,我正在同一個線程上做動畫,網格被創建。所以我認爲在這種情況下不需要Invoke。請糾正我,如果我在我的appraoch錯誤 –

+0

您收到的錯誤是一個調用問題,您是否嘗試過調用? –

+0

Rikshoy ..我試圖調用我的動畫代碼Dispatcher.Invoke(新的行動(()=> { _frontRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty,frontAnimation); _backRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty,backAnimation); 相機.BeginAnimation(PerspectiveCamera.PositionProperty,cameraZoomAnim); this.IsRotating = true; this.IsRotated = true; }));但沒有成功:( –

1

上面您的代碼是好的。無論問題出在哪裏,它都是MyUserControl中的東西 - 這些類中必須有共享元素,或者對主線程擁有的對象的引用。您必須確保MyUserControl內部已經創建或主線程擁有,包括作爲參數傳遞的對象等。

或者,您可能試圖使用主線程與(或與組件裏面)MyUserControl。如果你想從外螺紋(即:主線程,等等)上執行ctrl任何行動,你必須參考保持到ctrl和使用調用 - 這樣的事情:

public partial class MainWindow : Window 
{ 
    UserControl1 ctrl; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     Thread winthread = new Thread(new ThreadStart(() => 
     { 
      SynchronizationContext.SetSynchronizationContext(
       new DispatcherSynchronizationContext(
        Dispatcher.CurrentDispatcher)); 
      Window windowObj = new Window(); 
      Grid gridObj = new Grid(); 
      ctrl = new UserControl1(); 
      gridObj.Children.Add(ctrl); 
      windowObj.Content = gridObj; 

      windowObj.Show(); 
      System.Windows.Threading.Dispatcher.Run(); 
     })); 

     winthread.IsBackground = true; 
     winthread.SetApartmentState(ApartmentState.STA); 
     winthread.Start(); 
    } 

    private void button2_Click(object sender, RoutedEventArgs e) 
    { 
     ctrl.Dispatcher.Invoke(new Action(() => ctrl.AddStuff())); 
    } 
} 

在這裏,我做了UserControl1一個列表框一個簡單的窗口:

public partial class UserControl1 : UserControl 
{ 
    private int i; 

    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    public void AddStuff() 
    { 
     listBox1.Items.Add("This is line : " + i.ToString()); 
     i += 1; 
    } 
} 

你必須確保主線程使用調用上面的情況 - 特別是它看起來ctrl的調度程序來處理調用。主線程marshalls調用ctrl的調度程序,而不是使用自己的調度程序(導致交叉線程錯誤)。

如果您至少可以在MyUserControl內顯示出現異常的代碼行,這將有所幫助。

+0

感謝@J ..爲您的寶貴建議,我將確保驗證上面提到的我的代碼中的東西,並會讓你知道我是否會取得任何成功:) –

相關問題