c#多线程窗口假死的问题

qq_16488883 2014-06-26 05:18:34
 private string status = "Waiting for command";
private void send( string data1, stringdata2)
{
try
{
status = "Attempting to server....";

TAT = true;
timeRemaining = int.Parse(time);
System.Threading.Thread dThread = new System.Threading.Thread(new System.Threading.ThreadStart(countDown));
dThread.IsBackground = true;
dThread.Start();

}
catch
{
TAT = false;
MessageBox.Show("Connection error");
}
}
private void displayStatus()
{
for (; ; System.Threading.Thread.Sleep(1000))
{
label7.Text = status;
}
}
private void countDown()
{
for (; ; System.Threading.Thread.Sleep(1000))
{
try
{
if (TAT)
{
timeRemaining--;
status = string.Format("Attack has {0} time remainging", timeRemaining);
if (timeRemaining <= 0)
{
TAT = false;
break;
}
}
}
catch
{

}

}
}


这是一个按钮点击后进行TAT,并且进行TAT的时间计算,开始倒数计时,但是点击按钮后,窗口出现假死了,求怎么解决
...全文
319 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 9 楼 sunny906 的回复:
用invoke

this.label7.Invoke(new Action(()=>label7.Text = status));
把label7.Text = status;改为label7.Invoke(new Action(()=>label7.Text = status));? 还是不行
sunny906 2014-06-27
  • 打赏
  • 举报
回复
用invoke

this.label7.Invoke(new Action(()=>label7.Text = status));
smthgdin_020 2014-06-27
  • 打赏
  • 举报
回复
主线程阻塞了?前2天还有人说起这个问题。可以翻翻帖子。看球去了。。。。。
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 7 楼 sunny906 的回复:

        private void displayStatus()
        {
            for (; ; System.Threading.Thread.Sleep(1000))
            {
                label7.Text = status;
            }
        }
上面这段代码放到线程里了么,如果在线程里,那么label7就得用invoke了;如果没有在线程里,那么界面假死就很正常了
"线程间操作无效: 从不是创建控件“label7”的线程访问它。
sunny906 2014-06-27
  • 打赏
  • 举报
回复

        private void displayStatus()
        {
            for (; ; System.Threading.Thread.Sleep(1000))
            {
                label7.Text = status;
            }
        }
上面这段代码放到线程里了么,如果在线程里,那么label7就得用invoke了;如果没有在线程里,那么界面假死就很正常了
  • 打赏
  • 举报
回复
上面代码:
 this.label7.Invoke(new Action(()=> label7.Text = status));
这句有问题,如果你只是想更新UI控件状态,应该用BeginInvoke而不是Invoke ,Invoke 会等待主线程界面控件状态更新后,再继续执行,调用者线程将被阻塞。
sunny906 2014-06-27
  • 打赏
  • 举报
回复
不客气,弄好了就好
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 27 楼 sunny906 的回复:

                Thread thread = new Thread(new ThreadStart(() =>
                {
                    SshClient sshClient = new SshClient("1111", "222", "3333");
                    sshClient.Connect();
                    sshClient.RunCommand(string.Format("ads.pl {0} {1} {2} {3}", ip, port, pSize, time));
                    sshClient.Disconnect();
                }));
谢谢我弄好了
於黾 2014-06-27
  • 打赏
  • 举报
回复
所有通信相关的代码都应该放到线程里. 通信是很慢的(比起CPU来说),你让主线程建立通信,一定会阻塞UI
sunny906 2014-06-27
  • 打赏
  • 举报
回复

                Thread thread = new Thread(new ThreadStart(() =>
                {
                    SshClient sshClient = new SshClient("1111", "222", "3333");
                    sshClient.Connect();
                    sshClient.RunCommand(string.Format("ads.pl {0} {1} {2} {3}", ip, port, pSize, time));
                    sshClient.Disconnect();
                }));
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 25 楼 sunny906 的回复:
[quote=引用 23 楼 qq_16488883 的回复:] [quote=引用 20 楼 sunny906 的回复:] 跟上面一样把注释的部分同样地注释掉也会假死?
不对啊,连上服务器就会假死,不把SSH的部分注释掉,就会假死[/quote] 说明是sshClient方法引起的阻塞,那你把sshClient的方法也放进线程里[/quote] 怎么放?真心不懂,头都大了,我很新手的
sunny906 2014-06-27
  • 打赏
  • 举报
回复
引用 23 楼 qq_16488883 的回复:
[quote=引用 20 楼 sunny906 的回复:] 跟上面一样把注释的部分同样地注释掉也会假死?
不对啊,连上服务器就会假死,不把SSH的部分注释掉,就会假死[/quote] 说明是sshClient方法引起的阻塞,那你把sshClient的方法也放进线程里
abutwang 2014-06-27
  • 打赏
  • 举报
回复
backgroundworker。。。。
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 20 楼 sunny906 的回复:
跟上面一样把注释的部分同样地注释掉也会假死?
不对啊,连上服务器就会假死,不把SSH的部分注释掉,就会假死
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 20 楼 sunny906 的回复:
跟上面一样把注释的部分同样地注释掉也会假死?
谢谢,我知道了,我把里面的一部分数据弄错了,好了,谢谢啊
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 20 楼 sunny906 的回复:
跟上面一样把注释的部分同样地注释掉也会假死?
对的,一样会假死
sunny906 2014-06-27
  • 打赏
  • 举报
回复
跟上面一样把注释的部分同样地注释掉也会假死?
qq_16488883 2014-06-27
  • 打赏
  • 举报
回复
引用 16 楼 sunny906 的回复:

          int timeRemaining = 0;
        static List<string> leagueList;
        private bool bAttacking = false;
        private string status = "Waiting for command";
        private void sendDrop(string ip, string port, string pSize, string time)
        {
            try
            {
                status = "Attempting to connect to server....";
                //SshClient sshClient = new SshClient("1111", "222", "3333");
                //sshClient.Connect();


                bAttacking = true;
                timeRemaining = int.Parse(time);
                System.Threading.Thread dThread = new System.Threading.Thread(new System.Threading.ThreadStart(countDown));
                dThread.IsBackground = true;
                dThread.Start();


                //sshClient.RunCommand(string.Format("ads.pl {0} {1} {2} {3}", ip, port, pSize, time));
                //sshClient.Disconnect();
            }
            catch 
            {
                bAttacking = false;
                MessageBox.Show("Connection error");
            }
        }
        private void displayStatus()
        {
            for (; ; System.Threading.Thread.Sleep(1000))
            {
               this.label7.Invoke(new Action(()=> label7.Text = status));
            }


        }
        private void countDown()
        {
            for (; ; System.Threading.Thread.Sleep(1000))
            {
                try
                {
                    if (bAttacking)
                    {
                        timeRemaining--;
                        status = string.Format("Attack has {0} time remainging", timeRemaining);
                        if (timeRemaining <= 0)
                        {
                            break;
                        }
                        //bAttacking = false;
                    }
                    //bAttacking = false;
                }
                catch
                {


                }


            }
        }
        private void Form3_Load(object sender, EventArgs e)
        {
            System.Threading.Thread dThread = new System.Threading.Thread(new System.Threading.ThreadStart(displayStatus));
            dThread.IsBackground = true;
            dThread.Start();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sendDrop("", "", "", "1000");
        }
帮你调了下,不太明白为什么要把countDown()方法里的bAttacking设置为false,所以我就把bAttacking = false;注释掉了,在vs2010下测试界面里label的内容是变化的
我用的是2013,还是不行,除非时间到,不然一直假死状态,不能动。
 private void button1_Click(object sender, EventArgs e)
        {
            if (checkLad())
            {
                if (!bAttacking)
                {
                    sendDrop(darta1,data2, "data3", data4);
                }
                else
                    MessageBox.Show("Please wait");
            }
            else MessageBox.Show("Please got");
        }
这事botton里面的事件
sunny906 2014-06-27
  • 打赏
  • 举报
回复
你设计的初衷应该是想通过bAttacking来控制status的变化,可是你把bAttacking设置为false之后就没有再改变bAttacking的状态,所以label的内容就不会发生改变
sunny906 2014-06-27
  • 打赏
  • 举报
回复

          int timeRemaining = 0;
        static List<string> leagueList;
        private bool bAttacking = false;
        private string status = "Waiting for command";
        private void sendDrop(string ip, string port, string pSize, string time)
        {
            try
            {
                status = "Attempting to connect to server....";
                //SshClient sshClient = new SshClient("1111", "222", "3333");
                //sshClient.Connect();


                bAttacking = true;
                timeRemaining = int.Parse(time);
                System.Threading.Thread dThread = new System.Threading.Thread(new System.Threading.ThreadStart(countDown));
                dThread.IsBackground = true;
                dThread.Start();


                //sshClient.RunCommand(string.Format("ads.pl {0} {1} {2} {3}", ip, port, pSize, time));
                //sshClient.Disconnect();
            }
            catch 
            {
                bAttacking = false;
                MessageBox.Show("Connection error");
            }
        }
        private void displayStatus()
        {
            for (; ; System.Threading.Thread.Sleep(1000))
            {
               this.label7.Invoke(new Action(()=> label7.Text = status));
            }


        }
        private void countDown()
        {
            for (; ; System.Threading.Thread.Sleep(1000))
            {
                try
                {
                    if (bAttacking)
                    {
                        timeRemaining--;
                        status = string.Format("Attack has {0} time remainging", timeRemaining);
                        if (timeRemaining <= 0)
                        {
                            break;
                        }
                        //bAttacking = false;
                    }
                    //bAttacking = false;
                }
                catch
                {


                }


            }
        }
        private void Form3_Load(object sender, EventArgs e)
        {
            System.Threading.Thread dThread = new System.Threading.Thread(new System.Threading.ThreadStart(displayStatus));
            dThread.IsBackground = true;
            dThread.Start();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sendDrop("", "", "", "1000");
        }
帮你调了下,不太明白为什么要把countDown()方法里的bAttacking设置为false,所以我就把bAttacking = false;注释掉了,在vs2010下测试界面里label的内容是变化的
加载更多回复(10)

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧