我有一个带有进度条的表单(使用VS2010在C#中开发)。这是一种秒表表单,我在其中填充进度条,比如说10秒...随着时间的推移,进度条相应地填充...意味着5秒后,进度条将填充50%等等...
我使用了for循环来执行这个操作:-
for(int count=0;count<200;count++)
{
progbar.performstep();
progbar.update();
update();
Thread.Sleep(50);
}
我已经使用了线程。睡眠50毫秒,使进度条更新顺利。为1秒,它递增的步骤。
问题是,如果我执行任何其他操作,如移动此表单,甚至单击桌面上的另一个图标,会使此表单“无响应”....但它会执行操作,并在10秒结束时恢复其状态,并显示弹出窗口,指示10秒已过,进度条已满。
谢谢你的帮助,抱歉用了这么复杂的语言。
问候你Swanand
更新:我在下面答案的帮助下解决了这个问题....我了解到的一个常见错误是忘记了“Applications.DoEvents()
“沿着“update()
“....如果你输入这一行,被“挂”的机会就小多了!
5条答案
按热度按时间vybvopom1#
您正在UI线程上执行一个长时间运行的操作,这意味着UI“消息循环”(负责处理用户输入和更新屏幕等事件)没有机会运行。
您应该在另一个线程上执行长时间运行的操作(无论是您自己创建的线程还是后台线程),并使用
BackgroundWorker
轻松更新进度条,或者在需要更新UI时使用Control.Invoke/BeginInvoke
马歇尔委托调用封送回UI线程。(您一定不要从错误的线程更新控件。如果您唯一的UI交互是填充进度条,我建议使用
BackgroundWorker
。如果你不是真的在做“真正的”工作,只是在等待时间的流逝,你可以使用
System.Windows.Forms.Timer
来代替所有这些,然而。这将在UI线程上“滴答”,但不会在滴答之间阻塞UI线程。你应该只在你没有太多工作要做的时候使用它--如果它 * 真的 * 只是更新一个进度条,而不是(比如)处理文件等。请注意,您不应该依赖于计时器准确地“准时”触发-您可能应该根据观察到的时间而不是观察到的滴答数来设置进度条的位置。omhiaaxx2#
你阻塞了UI线程,这意味着它没有处理诸如“paint”之类的事件。要正确地做到这一点,你应该使用类似
BackgroundWorker
的东西,并且只从progress事件更新UI。dy1byipe3#
您正在阻塞主UI线程。您可以使用后台工作线程来执行此操作。您可以在MSDN中找到更多详细信息
uwopmtnx4#
如果你想运行你的代码,你应该把这个代码放在一个函数中,并用一个线程调用这个函数。
sleep(100)将停止整个上下文,而不是您想要的特定上下文。
7ivaypg95#
Marc建议的答案会有帮助。Lon运行操作会使你的应用程序崩溃或没有响应。我有一篇博客文章与后台工人类的使用有关。
http://midnightprogrammer.net/post/Using-Background-Worker-in-C.aspx