c#窗体假死

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#窗体假死相关的知识,希望对你有一定的参考价值。

我有两个按钮,button1 和 button2 还有一个richtext,我的想法是,一个公共变量message,点击button1后,richtext开始刷新(如果message为true),点击button2后停止,下述代码仍然会导致ui死掉,点不动button2,请教解决办法。

private Boolean message = true;

private void button1_Click(object sender, EventArgs e)


if (this.textBox1.Text==string.Empty && this.textBox2.Text==string.Empty)

MessageBox.Show("请配置参数!");

else

this.button1.Enabled = false;
try

System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ThreadStart(this.uploader));
th.IsBackground = true;
th.Start();

catch(Exception ems)

MessageBox.Show(ems.ToString());




private void uploader()

while (message)

new Thread((ThreadStart)(delegate()

this.richTextBox1.Invoke((MethodInvoker)delegate()

if (this.richTextBox1.Lines.Length > 100)

this.richTextBox1.Clear();

richTextBox1.Focus(); //让文本框获取焦点
richTextBox1.Select(richTextBox1.TextLength, 0);//设置光标的位置到文本尾
richTextBox1.ScrollToCaret();//滚动到控件光标处
richTextBox1.AppendText("线程启动!!!/n");//添加内容
richTextBox1.Refresh();

);
)).Start();



```

```

private void button2_Click(object sender, EventArgs e)


button1.Enabled = true;
message = false;

//问题不大,改成这样就行了:
void button1_Click(object sender, EventArgs e)

if (this.textBox1.Text==String.Empty && this.textBox2.Text==String.Empty)

MessageBox.Show("请配置参数!");

else

this.button1.Enabled = false;
message = true;
try

System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ThreadStart(this.uploader));
th.IsBackground = true;
th.Start();

catch(Exception ems)

MessageBox.Show(ems.ToString());




void button2_Click(object sender, EventArgs e)

button1.Enabled = true;
message = false;


private void uploader()

while (message)

new Thread((ThreadStart)(delegate()

this.richTextBox1.Invoke((MethodInvoker)delegate()

if (this.richTextBox1.Lines.Length > 100)

this.richTextBox1.Clear();

richTextBox1.Focus();
richTextBox1.Select(richTextBox1.TextLength, 0);
richTextBox1.ScrollToCaret();
richTextBox1.AppendText("线程启动!!!"+(n++)+"\n");
richTextBox1.Refresh();
);
)).Start();
Thread.Sleep(500);


private bool message = true;
private int n=1;
参考技术A

给你看一段我的代码片段吧,功能是:多线程上传商品信息到服务器,并且输出文本到richtextbox。界面还有其他同步任务,订单下载,订单上传等。窗体不会卡死。当然在某个特殊时间节点,所有任务都启动的时候,会有短暂的卡顿,然后窗体会恢复正常,这是没办法的,因为对的时候,有十多个同步任务,并且都是多线程执行,电脑系统资源占用大,CPU负载最高满载100%。

/// <summary>
    /// 上传商品
    /// </summary>
    /// <param name="rt"></param>
    /// <param name="bupdate"></param>
    public static void MedicineUpdate(RichTextBox rt, bool bupdate)
    
        if (FbMedicine_Doing)
            return;
        FbMedicine_Doing = true;
        try
        
            Log("正在获取药品信息……", rt);
            DataTable dt = xjm.GetMedicine(bupdate);
            if (dt.Rows.Count == 0)
                return;
            Log("找到药品记录:" + dt.Rows.Count.ToString(), rt);
            int iRowCount = dt.Rows.Count;
            int iThCount = ulSystem.StrToInt(Math.Ceiling(double.Parse(iRowCount.ToString()) / 1000).ToString());
            int iFrom = 0, iTo = 1000, iPage = 1000;
            string sql = "";
            List<string> templist = new List<string>();
            for (int ith = 0; ith < iThCount; ith++)
            
                templist.Clear();
                iFrom = iPage * ith;
                iTo = iPage * (ith + 1);
                if (iTo > iRowCount)
                    iTo = iRowCount;
                for (int i = iFrom; i < iTo; i++)
                
                    // sql = pt.FmtMedicineSQL(dt.Rows[i]);
                    sql = pt.FmtMedicineSQL_Auto(dt.Rows[i]);
                    templist.Add(sql);
                
                //创建线程
                Log("创建线程:" + (ith + 1).ToString(), rt);
                ThreadUpdateStock ths = new ThreadUpdateStock(templist, null, 4, ith);
                ths.Execute();
                ulSystem.Delay(2000);
            
        
        catch (Exception ex)
        
            Log("异常:" + ex.Message, rt);
        
        finally
        
            Log("上传药品信息执行结束。", rt);
            Log("", rt);
            FbMedicine_Doing = false;
        
    

其中需要用到一个延时方法,主要使用的是application.doevents().

代码如下:

    /// <summary>
    /// 非独占延时(毫秒)
    /// </summary>
    /// <param name="milliSecond">延时间隔(毫秒)</param>
    public static void Delay(int milliSecond)
    
        int start = Environment.TickCount;
        while (Math.Abs(Environment.TickCount - start) < milliSecond)
        
            Application.DoEvents();
        
    

参考技术B 如果是用控制台的话,是不会有问题的;
如果是用窗体的话,就要用线程。
增加一个引用
using System.Threading;
然后弄一个线程出来
Thread asd = new Thread(abc)
asd.Start();
abc()

for(int i = 0;i==i;i++)
{}
追问

窗体已经开了线程了,在点击button1后开启一个后台线程,一直刷新richtext,点击button2后更改公共值,但是这时候窗体假死了,停不了。我代码里面写了。

参考技术C using System.Threading;

以上是关于c#窗体假死的主要内容,如果未能解决你的问题,请参考以下文章

C# 委托 线程 窗体假死

c#解决窗体假死的一种方法

我用C# winform多线程,窗口就假死,等到线程全部完成了才可以点击。请问要怎么才可以让窗口不假死。

vb.net 多线程 窗体 假死

C#异步调用,界面假死

C#程序窗口假死