我希望它执行代码的第一部分,然后使pictureBox可见,暂停3秒,隐藏pictureBox并执行其余代码:
// first part of the code here
pb_elvisSherlock.Visible = true;
Thread.Sleep(300);
pb_elvisSherlock.Visible = false;
// rest of the code here
但它会执行整个代码块,然后才会暂停。任何想法该怎么做?
谢谢!
答案 0 :(得分:11)
如果您尝试使PictureBox
显示3秒钟,您可能希望应用程序在此期间保持响应。所以使用Thread.Sleep
不是一个好主意,因为你的GUI线程在睡觉时不会处理消息。
更好的选择是将System.Windows.Forms.Timer
设置为3000毫秒,在3秒后隐藏PictureBox
而不会阻止您的GUI。
例如,像这样:
pb.Visible = true;
var timer = new Timer();
timer.Tick += () => { pb.Visible = false; timer.Stop(); };
timer.Interval = 3000;
timer.Start();
答案 1 :(得分:5)
pb_elvisSherlock.Visible = true;
Application.DoEvents(); //let the app show the picturebox
Thread.Sleep(3000);
pb_elvisSherlock.Visible = false;
问题是,在暂停GUI线程之前,不要给消息循环提供显示图片框的机会。 Application.DoEvents()
解决了这个问题。
请注意,使用Thread.Sleep
GUI线程上会使绘画冻结(尝试通过应用程式移动窗口时,Sleep
是激活的)。
你应该这样做:
pb_elvisSherlock.Visible = true;
int counter = 0;
while (counter < 30)
{
Application.DoEvents();
Thread.Sleep(100);
++counter;
}
pb_elvisSherlock.Visible = false;
它仍然是一种黑客攻击,但窗口将重新绘制并按原样响应。
更新2
好。 DoEvents
似乎有点像黑客。 (感谢评论)。
如果图片框是一种唠叨屏幕,请执行以下操作:
备选方案1
Close
的表单中添加一个计时器该解决方案可以防止您的用户以“正常”形式执行任何操作,同时可以看到nagform。
备选方案2
答案 2 :(得分:3)
问题是你正在阻止UI线程,这是负责重新绘制表单的线程,因此在你等待的3秒内没有任何东西被重绘(尝试在这3秒内拖动你的表单并且你会发现它完全没有反应。)
有很多方法可以解决这个问题,但基本的前提是首先需要在后台线程上等待,以便你的UI线程保持响应(选项包括使用BackgroundWorker,{{ 3}},Timer,ThreadPool或Thread TPL)。其次,您必须记住,UI的任何更新都必须在UI线程上完成,因此您必须切换回UI线程(使用TaskFactory或.Invoke()),然后再隐藏图片框结束。
此示例使用TPL(任务并行库):
// Start by making it visible, this can be done on the UI thread.
pb_elvisSherlock.Visible = true;
// Now grab the task scheduler from the UI thread.
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
// Now create a task that runs on a background thread to wait for 3 seconds.
Task.Factory.StartNew(() =>
{
Thread.Sleep(3000);
// Then, when this task is completed, we continue...
}).ContinueWith((t) =>
{
//... and hide your picture box.
pb_elvisSherlock.Visible = false;
// By passing in the UI scheduler we got at the beginning, this hiding is done back on the UI thread.
}, uiScheduler);
答案 3 :(得分:1)
我会尝试延长时间:
Thread.Sleep(300);
更改为
Thread.Sleep(3000);
您的示例中仅暂停.3秒(3000 = 3秒)。如果我不得不猜测,你没有等待足够长的时间来显示窗口。代码实际上正常工作。
与评论一样,请在设置可见性属性后添加Application.DoEvents();
。
答案 4 :(得分:1)
答案 5 :(得分:0)
在这种情况下,扩展非常有用; - )
public static class IntExtensions
{
public static TimeSpan Seconds(this int value)
{
return new TimeSpan(0, 0, value);
}
}
Thread.Sleep(3.Seconds());
答案 6 :(得分:0)
无论Thread.Sleep方法有时不会阻塞线程,您都可以尝试使用此Task.Delay(TimeSpan.FromSeconds(3)).Wait();
。