如何检查表格仍然“活着”

时间:2010-09-07 07:05:04

标签: c# multithreading

我在一个单独的线程中加载一个大的树视图。该线程从表单的load事件开始。

一切顺利,直到load事件发生错误。发生错误时,我关闭表单,并且必须中止加载我的treeview的线程。但我不知道该怎么做。

问题是,表单已关闭且线程仍在工作,因此我得到InvalidOperationException。该程序崩溃,并突出显示该部分线程:

tvQuestionnaire.Invoke((MethodInvoker)delegate
{
    tvQuestionnaire.Nodes.Add(catNode);
});

我表单上的树视图名为tvQuestionnaire。整个函数(在我的后台工作程序中调用)看起来像这样:

private void SetTreeviewData()
{
    // Get all categories
    List<Category> categories = _questionnaire.GetCategoriesFromQuestionnaire();

    // Get all questions which are retrieved by the question manager
    OrderedDictionary all_ordered_questions = _questionManager.AllQuestions;

    // Store all the questions in a List<T>
    List<Question> all_questions = new List<Question>();
    foreach (DictionaryEntry de in all_ordered_questions)
    {
        Question q = de.Value as Question;
        all_questions.Add(q);
    }

    foreach (Category category in categories)
    {
        // Create category node
        TreeNode catNode = new TreeNode();
        catNode.Text = category.Description;
        catNode.Tag = category;
        catNode.Name = category.Id.ToString();

        // Get all questions which belongs to the category
        List<Question> questions = all_questions.FindAll(q => q.CategoryId == category.Id);

        // Default set the font to bold (Windows issue)
        Font font = new Font(tvQuestionnaire.Font, FontStyle.Regular);

        foreach (Question question in questions)
        {
            // Create question node
            TreeNode queNode = new TreeNode();
            queNode.Text = question.Question;
            queNode.Tag = question;
            queNode.Name = "Q" + question.Id;
            queNode.NodeFont = font;

            // Determine which treenode icon to show
            SetTreeNodeIcon(ref queNode, question);

            // Add node to category node
            catNode.Nodes.Add(queNode);
        }

        if (_closing)
            return;

        // Add category node to treeview
        tvQuestionnaire.Invoke((MethodInvoker)delegate
        {
            tvQuestionnaire.Nodes.Add(catNode);

            // Now the category (and thus the questions) are added to treeview
            // Set questions treenode icon
            //SetTreeNodeIcon(questions);
        });
    }

    // Set each category under its parent
    for (int i = tvQuestionnaire.Nodes.Count - 1; i >= 0; i--)
    {
        Category category = tvQuestionnaire.Nodes[i].Tag as Category;
        TreeNode node = tvQuestionnaire.Nodes[i];

        if (IsWindow(this.Handle.ToInt32()) == 0)
            return;

        tvQuestionnaire.Invoke((MethodInvoker)delegate 
        {
            if (category.ParentId == null)
                return;
            else
            {
                // Find parent node
                TreeNode[] parentNodes = tvQuestionnaire.Nodes.Find(category.ParentId.ToString(), true);

                //Remove current node from treeview
                tvQuestionnaire.Nodes.Remove(node);
                parentNodes[0].Nodes.Insert(0, node);
            }
        });
    }
}

这是我的后台工作者调用的唯一方法。

所以我的问题是,如何防止异常发生?如何查看树视图所在的表单,还是“活着”?

3 个答案:

答案 0 :(得分:2)

一种解决方案是在需要关闭表单时调用backgroundworker(BGW)的CancelAsync方法。在DoWork事件处理程序中,在循环开始时检查是否未请求取消。如果是,退出循环(和DoWork处理程序)。 在表单中,等待BGW完成(成功或取消)

答案 1 :(得分:0)

为什么不抓住这个事件,而不是中止线程的执行?

答案 2 :(得分:0)

检查表单的IsHandleCreated属性。如果表格仍然存在,那将是真的。