在while中调用Thread.Sleep()时,界面假死了

寒冰2046 2010-11-02 02:24:59
在while中调用Thread.Sleep(3000)时,也就是3秒左右时,界面假死了。这个能解决么?只要能控件一定时间后再进行下一次循环就行了。

while(IsXXX()==false)
{
Thread.Sleep(3000);
}
...全文
1446 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
程序高手 2013-03-13
  • 打赏
  • 举报
回复
Application.DoEvents();防止假死 对的 非常对
qq31516369 2012-06-14
  • 打赏
  • 举报
回复
Application.DoEvents();
System.Threading.Thread.Sleep(100);
防假死
达不溜来多多 2010-11-11
  • 打赏
  • 举报
回复
C# code
ssss
寒冰2046 2010-11-11
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 linkor 的回复:]

引用 14 楼 wuyazhe 的回复:

C# code

//Thread.Sleep(3000);
替换为
int n = Environment.Tick;
while(Environment.Tick-n<3000) Application.DoEvents();
这个方法同样存在CPU占用高的问题。但是我意外地发现了另一个现象,在调试模式下,注意:是调试模式,增加了 ……
[/Quote]
其实Environment.TickCount并没有发挥作用,因为以下两段代码的CPU占用率是相差无几的。

int counter = 0;
while (isRunning == true)
{
counter++;
Console.WriteLine(counter);
Application.DoEvents();
}




int n = 0;
int counter = 0;
while (isRunning == true)
{
n = Environment.TickCount;
while (Environment.TickCount - n < 3000)
{
counter++;
Console.WriteLine(counter);
Application.DoEvents();
}
}
寒冰2046 2010-11-11
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wuyazhe 的回复:]

C# code

//Thread.Sleep(3000);
替换为
int n = Environment.Tick;
while(Environment.Tick-n<3000) Application.DoEvents();
[/Quote]这个方法同样存在CPU占用高的问题。但是我意外地发现了另一个现象,在调试模式下,注意:是调试模式,增加了 Console.WriteLine("")调用,结果CPU占用下降到了1%以下!
int n = 0;
while (isRunning == true)
{
n = Environment.TickCount;
while (Environment.TickCount - n < 3000)
{
Console.WriteLine("");
Application.DoEvents();
}
}


不过,如果是直接运行(不调试),那么CPU占用又接近50%了。我想这应该因为是Console.WriteLine("");占用了时间,所以循环的次数大大减少了。但是程序在运行时我找不到让程序代替Console.WriteLine("")而做无用功的方法。。不然可以作为暂时解决方法。以下是测试代码:

int n = 0;
int counter = 0;
while (isRunning == true)
{
//Application.DoEvents();
n = Environment.TickCount;
while (Environment.TickCount - n < 3000)
{
counter++;
Console.WriteLine(counter);
Console.WriteLine(Environment.TickCount);
Application.DoEvents();
}
}

结果显示,在while (Environment.TickCount - n < 3000)循环中,只进行了约128次循环。而在下面的代码中,进行了约300万次循环。

int n = Environment.TickCount;
int counter = 0;
while (Environment.TickCount - n < 3000)
{
counter++;
Application.DoEvents();
}
寒冰2046 2010-11-11
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sp1234 的回复:]

简单修改可以写:
C# code
while(IsXXX()==false)
{
Application.DoEvents();
}
.....//然后继续干你的事。
[/Quote]用这方法界面已经能响应操作了,但是引出了另外一个问题:CPU占用相当的高,我的2U4线程,能占到50%!根据我的理解,Application.DoEvents()只是使得程序响应界面操作,但是事实上没有实现定时调用IsXXX()。
求良方。。。
兔子-顾问 2010-11-05
  • 打赏
  • 举报
回复

//Thread.Sleep(3000);
替换为
int n = Environment.Tick;
while(Environment.Tick-n<3000) Application.DoEvents();
  • 打赏
  • 举报
回复
简单修改可以写:
while(IsXXX()==false)
{
Application.DoEvents();
}
.....//然后继续干你的事。
jhly_zhk 2010-11-05
  • 打赏
  • 举报
回复
调用Sleep方法的是类本身,而不是类的实例。休眠的是该语句所在的线程,而不是其他线程。
寒冰2046 2010-11-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 vrhero 的回复:]

改用Timer组件或后台线程...Windows UI是单元线程,你阻赛UI线程能响应才怪...
[/Quote]
后台线程怎么让程序停留在等待状态呢?求具体点的指点。
寒冰2046 2010-11-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bloodish 的回复:]

如果是Windows 窗体应用程序
用这个Timer

Timer 类
[/Quote]
这个方法似乎无法停留在等待状态。
=====================================================================================
效果相当于一个监听功能:当满足条件时IsXXX()返回true,否则返回false。前提:总会到达满足条件的时候,但是时间不确定。如果没有满足条件,则一直等待下去,不执行另外的语句,但是界面要能够响应操作,否则这个监听就无法控制了。
代码如下:

private bool m_isLisening = true;

private void button1_Click(object sender, EventArgs e)
{
if (IsDoNext() == true)
{
//执行语句块A
}
else
{
//执行语句块B
}
}

private void button2_Click(object sender, EventArgs e)
{
//切换监听状态
if (m_isLisening == true)
{
m_isLisening = false;
}
else
{
m_isLisening = true;
}
}

private bool IsDoNext()
{
while (IsOK() == false && m_isLisening == true)
{
Thread.Sleep(3000);
}
}

private bool IsOK()
{
if (满足条件)
{
return true;
}
else
{
return false;
}
}

=====================================================================================
寒冰2046 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 karascanvas 的回复:]

上面的都说了,楼主有个写法可以改一下

while(IsXXX()==false) 可以写成 while(!IsXXX())
[/Quote]
我的风格是 IsXXX()==false ,这样感觉代码可读性好些即使是 while(IsXXX())一般也写成while(IsXXX()==true) ,当然很少在while里面这么做的,通常是if(IsXXX()==true)。

如果从性能上来说,我就不确定了。
IsXXX()==false 进行了一次比较,而!IsXXX()应该是一次运算,不知道哪个性能更好呢。
种草德鲁伊 2010-11-02
  • 打赏
  • 举报
回复
上面的都说了,楼主有个写法可以改一下

while(IsXXX()==false) 可以写成 while(!IsXXX())
寒冰2046 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bloodish 的回复:]

如果是Windows 窗体应用程序
用这个Timer

Timer 类
[/Quote]
很好。回头试试。
寒冰2046 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 vrhero 的回复:]

改用Timer组件或后台线程...Windows UI是单元线程,你阻赛UI线程能响应才怪...
[/Quote]
呵呵,明白了
寒冰2046 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lishenghu365 的回复:]

不要把这段代码放到主线程里面去,这样肯定假死的。新启动一个线程来执行这个方法就好了
[/Quote]
好,新开线程应该能解决。
bloodish 2010-11-02
  • 打赏
  • 举报
回复
如果是Windows 窗体应用程序
用这个Timer

Timer 类
bloodish 2010-11-02
  • 打赏
  • 举报
回复
用Timer.

Timer 类
  • 打赏
  • 举报
回复
不要把这段代码放到主线程里面去,这样肯定假死的。新启动一个线程来执行这个方法就好了
vrhero 2010-11-02
  • 打赏
  • 举报
回复
改用Timer组件或后台线程...Windows UI是单元线程,你阻赛UI线程能响应才怪...

111,089

社区成员

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

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

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