使用dispatcher.invoke时程序冻结

时间:2017-04-10 12:40:08

标签: c# wpf multithreading

我在数据库(类别,子类别)中有多个类别。 我想将子类别放入正常的类别中。 这是我的方法:

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);
        }
    }
}    

我尝试使用Threads暂停代码来调用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();全球。

但程序冻结了。如果我使用serviceList

,我在冻结程序时如何访问全局Dispatcher.Invoke

1 个答案:

答案 0 :(得分:0)

@Felype在评论中写道使用BeginInvoke代替Invoke。 这很有效。该程序不再冻结。感谢。

我在评论中宣称为答案的另一个问题也是通过以下方式解决的:

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

private void LoadUnderCategories(int categoryID, TreeView serviceList)

希望这是正确的方式。