2010-07-01 214 views
1

當另一個線程運行時,我有一個窗口顯示'工作'動畫。窗口顯示,我可以看到進度條,但動畫被凍結。該代碼運行在一個視圖模型,並在構造函數中創建調度:當另一個線程運行時,WPF動畫停止運行

​​

創建動畫和運行過程的代碼如下:

Working wrk;  
protected void Search() 
{ 
    ImplementSearch(); 

    wrk = new Working(); 
    wrk.Owner = (MainWindow)App.Current.MainWindow; 
    wrk.WindowStartupLocation = WindowStartupLocation.CenterOwner; 
    wrk.HeadingMessage = "Searching..."; 
    wrk.UpdateMessage = "Running your search"; 
    wrk.ShowDialog();  
} 

void ImplementSearch() 
{ 
    System.Threading.Thread thread = new System.Threading.Thread(
    new System.Threading.ThreadStart(
     delegate() 
     { 
     System.Windows.Threading.DispatcherOperation 
      dispatcherOp = _dispatcher.BeginInvoke(
      System.Windows.Threading.DispatcherPriority.Normal, 
      new Action(
      delegate() 
      {     
       ResetSearch(); 

       string ret = _searchlogic.PerformSearch(SearchTerm, ref _matchingobjects, TypeOfFilter()); 
       if (ret != null) 
       SearchMessage = ret; 

       if (_matchingobjects.Count > 0) 
       { 
       DataRow row; 
       foreach (SearchLogicMatchingObjects item in _matchingobjects) 
       { 
        row = _dt.NewRow(); 
        row["table"] = item.Table; 
        row["pk"] = item.PK; 
        _dt.Rows.Add(row); 
       } 

       SelectCurrent(); 
       }   
      } 
     )); 

     dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed); 
     } 
)); 

    thread.Start(); 
} 

void dispatcherOp_Completed(object sender, EventArgs e) 
{ 
    wrk.Close(); 
} 

我想不出爲什麼動畫停止?誰能幫忙? 謝謝

回答

2

我認爲你想在後臺線程上做實際的工作,而不是將所有事情都封送到UI線程,這就是BeginInvoke所做的!通過使用BeginInvoke在UI線程上執行所有操作,您的動畫將不會運行。

Working wrk;  
protected void Search() 
{ 
    ImplementSearch(); 

    wrk = new Working(); 
    wrk.Owner = (MainWindow)App.Current.MainWindow; 
    wrk.WindowStartupLocation = WindowStartupLocation.CenterOwner; 
    wrk.HeadingMessage = "Searching..."; 
    wrk.UpdateMessage = "Running your search"; 
    wrk.ShowDialog();  
} 

void ImplementSearch() 
{ 
    Thread thread = new Thread(new ThreadStart( 
     delegate() 
     { 
      // Call to function which changes UI - marshal to UI thread. 
      _dispatcher.BeginInvoke((Action)(() => ResetSearch())); 

      string ret = _searchlogic.PerformSearch(SearchTerm, ref _matchingobjects, TypeOfFilter()); 

      if (ret != null) 
      { 
       // Call to function which changes UI - marshal to UI thread. 
       _dispatcher.BeginInvoke((Action<string>)((r) => SearchMessage = r), ret); 
      } 

      if (_matchingobjects.Count > 0) 
      { 
      DataRow row; 
      foreach (SearchLogicMatchingObjects item in _matchingobjects) 
      { 
       row = _dt.NewRow(); 
       row["table"] = item.Table; 
       row["pk"] = item.PK; 
       _dt.Rows.Add(row); 
      } 

      // Call to function which changes UI - marshal to UI thread. 
      _dispatcher.BeginInvoke((Action)(() => SelectCurrent())); 
      }   
     } 

     wrk.Close(); 
    })); 
    thread.Start(); 
} 
+0

乾杯!我已經取得了一些成功,雖然它拋出了其他相關的問題。具體而言,當搜索返回多個匹配對象時,不會填充_matchingobjects列表。這個列表是在UI線程中聲明的,所以我想這就是問題所在。我也必須使用這個ObservableCollectionEx http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx來防止異常。將士兵與我的基本理解線程! – pilsdumps 2010-07-02 08:09:26

+0

從頭開始評論有關未被填充的列表 – pilsdumps 2010-07-02 08:17:19

+0

通常,您可以訪問任何線程上的_non-UI_對象,但是您需要注意多個線程不會同時讀取/寫入它們。此外,線程間的操作並不保證以任何順序進行,這通常是新手進行線程處理的錯誤來源。 – codekaizen 2010-07-02 08:53:59

0

您的線程沒有任何用處 - 通過使用_dispatcher.BeginInvoke來運行搜索,您將有效地在UI線程上執行搜索,從而阻止您的動畫。僅將後臺線程的調度程序用於操作UI控件或引發PropertyChanged事件的操作。