2017-04-10 89 views
0

我在數據庫(類別,子類別)有多個類別。 我想把子類別放入正常的類別。 這是我的方法:使用dispatcher.invoke時程序凍結

private void LoadCategories() 
{ 
    connection = new MySqlConnection(conf.connection_string); 
    MySqlCommand cmd = new MySqlCommand(); 
    cmd.Connection = connection; 
    cmd.CommandText = "SELECT * FROM auftrags_typ_category"; 

    if (this.OpenConnection() == true) 
    { 
     try 
     { 
      MySqlDataReader reader = cmd.ExecuteReader(); 
      while (reader.Read()) 
      { 
       int categoryID = (int)reader["id"]; 
       #region Create Expander 
       Expander cat_expander = new Expander(); 
       cat_expander.ExpandDirection = ExpandDirection.Right; 
       TextBlock cat_name = new TextBlock(); 
       cat_name.Text = reader["name"].ToString(); 
       cat_name.RenderTransformOrigin = new Point(0.5, 0.5); 
       cat_name.LayoutTransform = new RotateTransform() { Angle = 90 }; 
       cat_expander.Header = cat_name; 

       Thread t = new Thread(() => LoadUnderCategories(categoryID)); 
       t.SetApartmentState(ApartmentState.STA); 
       t.Start(); 
       t.Join(); 

       Border border = new Border(); 
       border.Width = 1; 
       border.VerticalAlignment = VerticalAlignment.Stretch; 
       border.SnapsToDevicePixels = true; 
       border.Background = (Brush)FindResource("MaterialDesignDivider"); 

       cat_expander.Content = serviceList; 
       serviceListSP.Children.Add(cat_expander); 
       serviceListSP.Children.Add(border); 

       serviceList.Items.Clear(); 
       #endregion 
      } 
     } 
     catch (MySqlException ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 
}  

我嘗試使用線程調用LoadUnderCategories暫停代碼:

private void LoadUnderCategories(int categoryID) 
{ 
    connection = new MySqlConnection(conf.connection_string); 
    MySqlCommand cmd = new MySqlCommand(); 
    cmd.Connection = connection; 
    cmd.CommandText = "SELECT * FROM auftrags_typ_childcategory WHERE category = @categoryID"; 
    cmd.Parameters.AddWithValue("@categoryID", categoryID); 

    if (this.OpenConnection() == true) 
    { 
     try 
     { 
      MySqlDataReader reader = cmd.ExecuteReader(); 
      while (reader.Read()) 
      { 
       TreeViewItem child_category = new TreeViewItem(); 
       child_category.Header = reader["name"].ToString(); 
       Application.Current.Dispatcher.Invoke((Action)(() => 
       { 
        serviceList.Items.Add(child_category); 
       })); 

      } 
     } 
     catch (MySqlException ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 
} 

我宣佈TreeView serviceList = new TreeView();全球。

但是程序凍結。如果我使用Dispatcher.Invoke,程序凍結時如何訪問全局serviceList

+2

嘗試將整個循環放入調度程序而不是僅添加函數,您在循環中調用調度程序,這可能是問題的一部分。 另外,嘗試使用BeginInvoke而不是Invoke(這是同步的),有可能在某一時刻,您的工作線程將同時等待UI線程和等待工作線程的UI線程。 – Felype

+0

它仍然凍結。 編輯: 隨着BeginInvoke它的作品。但它不會暫停。 我有3個子類別。 2有id 1,最後一個subcat有id 2. 但是所有的子類別都是以id 4結尾的最後一個類別。所以我認爲。 t.Join不起作用。因爲子郵件將添加到最後一個類別。 –

回答

0

@Felype在評論中寫道使用BeginInvoke而不是Invoke。 這工作。該程序不再凍結。謝謝。

TreeView serviceList = new TreeView(); 
Thread t = new Thread(() => LoadUnderCategories(categoryID, serviceList)); 

而且

private void LoadUnderCategories(int categoryID, TreeView serviceList) 

希望這就是正確的方法:

,我在評論中聲明爲回答另一個問題是過於固定。