C# 使用dispatcher.invoke时程序冻结
我在数据库中有多个类别(类别、子类别)。 我想把这些子类别归入普通类别。 这是我的方法:C# 使用dispatcher.invoke时程序冻结,c#,wpf,multithreading,C#,Wpf,Multithreading,我在数据库中有多个类别(类别、子类别)。 我想把这些子类别归入普通类别。 这是我的方法: private void LoadCategories() { connection = new MySqlConnection(conf.connection_string); MySqlCommand cmd = new MySqlCommand(); cmd.Connection = connection; cmd.CommandText = "SELECT * FRO
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);
}
}
}
我声明了treeviewservicelist=newtreeview()代码>全局
但是程序冻结了。如果我使用Dispatcher.Invoke
,当程序冻结时如何访问全局serviceList
?@fetype在注释中写到使用BeginInvoke
而不是Invoke
。
这起作用了。程序不再冻结。谢谢
我在评论中声明为答案的另一个问题也通过以下方式解决:
TreeView serviceList = new TreeView();
Thread t = new Thread( () => LoadUnderCategories(categoryID, serviceList) );
及
希望这是正确的方法。尝试将整个循环放在dispatcher中,而不仅仅是add函数,您在循环中调用dispatcher,这可能是问题的一部分。或者,尝试使用BeginInvoke而不是Invoke(这是同步的)。可能在某一点上,您的工作线程将同时等待UI线程和UI线程。它仍然会冻结。编辑:使用BeginInvoke它可以工作。但它不会停下来。我有三个子类。2的id为1,最后一个子类别的id为2。但所有子类别都会转到id为4的最后一个类别。所以我想。t、 Join不起作用。因为子类别将添加到最后一个类别。
private void LoadUnderCategories(int categoryID, TreeView serviceList)