C# TabPage冻结应用程序

C# TabPage冻结应用程序,c#,tabcontrol,tabpage,C#,Tabcontrol,Tabpage,我有一个TabControl,有几个TabPages。我想做的是改变标签,让它在不同的标签上调用richtextbox。我会试着在代码之后更好地表达这个问题 void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e) { switch(tabControl1.SelectedTab.Name) { case "tabPage_ProdOrd

我有一个TabControl,有几个TabPages。我想做的是改变标签,让它在不同的标签上调用richtextbox。我会试着在代码之后更好地表达这个问题

    void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
    {
        switch(tabControl1.SelectedTab.Name)
        {
            case "tabPage_ProdOrders":
                dostuff();
                break;
        }


        //throw new System.NotImplementedException();
    }

    void dostuff()
    {
        while (tabControl1.SelectedTab == tabControl1.TabPages["tabPage_ProdOrders"])
        {
            safeCall("testing...\n");
            Thread.Sleep(10000);
        }
    }

    delegate void SetTextCall(string s);

    public void safeCall(string s)
    {
        if (this.richTextBox1.InvokeRequired)
        {
            SetTextCall d = new SetTextCall(safeCall);
            this.Invoke(d, new object[] { s });
        }
        else this.richTextBox1.AppendText(string.Format(":{0}:\n",s));
    }

我知道它看起来很邋遢-对不起。所以richtextbox驻留在tabpage“tabpage_DEV”上。我试图做到的是,当我切换到tabpage“tabpage\u ProdOrders”时,让它将文本附加到“tabpage\u DEV”上的richtextbox中。此外,这是一个确保一切顺利运行的测试,我最终要做的是,一旦选择了“tabPage_ProdOrders”,我将有一个gridview绑定到我的数据库,只要选择了该页面,它将每隔X秒从数据库刷新一次。问题是,只要我选择“tabPage_ProdOrders”,整个应用程序就会冻结。我假设这是由于while循环中的线程.Sleep()(我的假设是,由于该空是窗口的一部分,因此当它是.Sleep()时,整个窗体是.Sleep()正确的?任何关于解决方法的指导都是非常好的。

在窗体中添加一个计时器,并对其Tick事件进行编码,以完成所有DB工作

更改dostuff方法,如下所示:

void dostuff()
{
    if (tabControl1.SelectedTab == tabControl1.TabPages["tabPage_ProdOrders"])
    {
        dbTimer.Interval = 10000; // your interval in ms
        dbTimer.Start();
    }
    else dbTimer.Stop();

}

使用Thread.Sleep(..)您发送当前的,即要睡眠的GUI线程。这不是您想要的。

我使用了与TaW的建议类似的方法

    delegate void populateProdOrders(DataTable dt);

    public void safePopulate(DataTable dt)
    {
        if (this.dataGridView2.InvokeRequired)
        {
            populateProdOrders d = new populateProdOrders(safePopulate);
            this.Invoke(d, new object[] { dt });
        }
        else this.dataGridView2.DataSource = dt;
    }

    public Form1()
    {
        // stuff
        System.Timers.Timer refreshProdOrders = new System.Timers.Timer(5000);
        refreshProdOrders.Elapsed += refreshProdOrders_Elapsed;
        refreshProdOrders.AutoReset = true;
        refreshProdOrders.Enabled = true;

    }

    void refreshProdOrders_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        //dostuff();
        var globes = SharedResourceVariables.globals;
        DataTable dt = new DataTable();

        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(globes.SQLConn);
        using (conn)
        {
            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("development_usp_viewProdductionOrders", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            using (cmd)
            {
                conn.Open();
                System.Data.SqlClient.SqlDataReader dr = cmd.ExecuteReader();
                dt.Load(dr);
                conn.Close();
            }
        }
        safePopulate(dt);
    }

您希望如何离开
while
循环?sob-dur…好的,我应该使while循环调用确定while循环的状态…类似while(method()){…sleep()};然后在method()中类似return(tabControl1.SelectedTab==tabControl1.TabPages[“tabPage\u ProdOrders”])?真:假;…但我仍然觉得这会挂在。睡眠正确吗?选项卡将如何更改?通过用户交互?在这种情况下,请不要在循环中等待它!!你为什么要调用睡眠?只是想知道:可能是你根本不懂GUI编程吗?你对用户做出反应,GUI完成所有等待..bec因为它需要在一个定时循环中从数据库刷新-有作业一直在数据库上运行更改数据。我的源绑定到该数据库。我需要在X个时间段后刷新,以避免数据库和连接过载。如果用户在该页面停留“永远”无论用户的交互如何,它都需要继续更新。选项卡控件是通过用户交互更改的。我希望避免线程旋转并执行此操作,然后在数据更改时触发事件,以更新网格-但这可能是最好的方式吗?我只是觉得它应该*是更多的东西mplistic。是的,这就是我假设发生的事情-我知道我做了一些愚蠢/错误的事情,但没有看到它。谢谢你给我指出相应的计时器。我确实在表单上使用了计时器,因为无论用户是否在该选项卡页上,更新该选项卡页都会更好。再次感谢!(FWIW,不,我通常不会编写GUI的代码)