首页 新闻 搜索 专区 学院

BeginInvoke 与 Invoke 阻塞UI问题

0
悬赏园豆:50 [已解决问题] 解决于 2012-08-21 15:34

很奇怪当我把     treeList1.Invoke((MethodInvoker)delegate

放在循环外边时 UI被阻塞了  代码执行顺序

 label1.Text = "111111111"--> GetTreeListBindings()--> MessageBox.Show("哇哈哈");

当按下面代码执行时,UI没有被阻塞

我想不阻塞UI。。还有什么办法吗?

        private void simpleButton2_Click(object sender, EventArgs e)
        {
            treeList1.ClearNodes();
            _thread = new Thread(new ThreadStart(delegate()
            {
                GetTreeListBindings();
            }));
            _thread.IsBackground = true;
            _thread.Start();


            label1.Text = "111111111";
            MessageBox.Show("哇哈哈");
    
        }

        private void GetTreeListBindings() 
        {
            DXTest01.BLL.Town_Village_Hos_Dictionary bll = new DXTest01.BLL.Town_Village_Hos_Dictionary();
            DataTable dt = new DataTable();
            DataTable dt_two = new DataTable();
            //查出父节点
            dt = bll.GetDataTable_sHosServerCode();
            //循环添加数据
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                treeList1.Invoke((MethodInvoker)delegate
                {
                    //绑定父节点
                    TreeListNode Node = treeList1.AppendNode(new object[]
                    { 
                        dt.Rows[i]["sHosServerCode"],
                        dt.Rows[i]["sHosServerName"], null, null, 
                        dt.Rows[i]["sMedComparison"]
                    }, null);
                    Node.SetValue(0, dt.Rows[i]["sHosServerCode"]);
                    //查询子节点
                    dt_two = bll.GetDataTable(dt.Rows[i]["sHosServerCode"].ToString());
                    //绑定子节点
                    for (int j = 0; j < dt_two.Rows.Count; j++)
                    {
                        this.treeList1.AppendNode
                        (new object[] 
                        {
                            dt_two.Rows[j]["sHosServerCode"],
                            dt_two.Rows[j]["sHosServerName"],
                            dt_two.Rows[j]["sVillageHosCode"],
                            dt_two.Rows[j]["sVillageHosName"],
                            dt_two.Rows[j]["sMedComparison"] 
                        }, Node);
                    }
                });
            }
        }
Baby_Face的主页 Baby_Face | 初学一级 | 园豆:157
提问于:2012-08-21 14:07
< >
分享
最佳答案
0

你自己标题里面不是写了吗?用BeginInvoke.

该方法会在线程池中自动分配线程为你的委托执行代码。

如果委托中有UI的更新,需要再次调用BeginInvoke回到主线程去更新UI状态数据。

收获园豆:25
Ethan轻叹 | 小虾三级 |园豆:996 | 2012-08-21 15:19

用BeginInvoke  也会阻塞,我试过了

Baby_Face | 园豆:157 (初学一级) | 2012-08-21 15:20

@Baby_Face:

private int SimulateWork() {
Thread.Sleep(10 * 1000);
return 100;
}
private void SetText(string va) {

this.label1.Text = va;
}
private void button1_Click(object sender, EventArgs e)
{
Func<int> act = new Func<int>(SimulateWork);
act.BeginInvoke((result) => {
int ret = act.EndInvoke(result);
this.label1.BeginInvoke(new Action<string>(SetText), ret.ToString());
},null);
SetText("10 seconds later, the text would be changed.");
}

Ethan轻叹 | 园豆:996 (小虾三级) | 2012-08-21 15:47

貌似我加这个也行Application.DoEvents();

Baby_Face | 园豆:157 (初学一级) | 2012-08-21 16:32
其他回答(1)
0

楼上的意思是只要你修改UI,就会占用主线程,就会阻塞。所以你应该尽量减少调用UI的次数,在你的辅助线程里先把数据准备好,然后再集中的一次性把你的树控件建立出来。

收获园豆:25
Launcher | 园豆:45045 (高人七级) | 2012-08-21 15:28
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册