【发布时间】:2013-04-11 03:20:08
【问题描述】:
我目前正在开发一个需要使用表单来阻止用户使用主表单几秒钟的应用程序。尽管在主线程上运行代码似乎没问题,但弹出表单上的标签在表单首次出现时大约一秒钟内不会呈现。我认为如果我在单独的线程上运行该表单,渲染会更加流畅。渲染现在非常流畅,渲染后表单立即消失。计时器设置为五秒钟,屏幕上的标签倒计时。下面是调用新线程和表单的相关代码:
System::Void MainScreen::runGame(int playerTurn) {
Thread ^ t = gcnew Thread(gcnew ThreadStart(gcnew MainScreen(),
&MainScreen::showModalDialog));
t->Start();
t->Join();
InitializeDice();
startTimer();
}
System::Void MainScreen::showModalDialog() {
GetReady ^ gr = gcnew GetReady();
gr->showModalPopup();
}
这是表单内的代码:
public:
GetReady(void)
{
InitializeComponent();
}
System::Void showModalPopup() {
this->Show();
startTimer();
}
private: System::Void timerPrep_Tick(System::Object^ sender, System::EventArgs^ e) {
ts = ts->Subtract(TimeSpan(0, 0, 1));
if (ts->TotalSeconds <= 0) {
finishTimer();
} else {
lblTimer->Text = ts->ToString("mm\\:ss");
}
}
System::Void startTimer() {
array<String ^>^ minSec = gcnew array<String ^>(2);
minSec = lblTimer->Text->Split(':');
ts = gcnew TimeSpan(0, Convert::ToInt32(minSec[0]), Convert::ToInt32(minSec[1]));
Thread::Sleep(900);
timerPrep->Start();
}
System::Void finishTimer() {
timerPrep->Stop();
lblTimer->Text = "GO!!!";
Thread::Sleep(900);
this->Close();
}
我理想的解决方案是使用线程生成新表单,这样主表单和弹出表单的渲染都很流畅。
我尝试过的事情:
- 将 this->Show() 移动到任何我能想到的地方。
- 我添加了 t->Join() 来查看主线程是否试图使主窗口重新聚焦。线程 t 仍在执行,并且计时器仍然与 Join 一起正常运行,阻止用户输入 5 秒钟 - 但没有任何东西可以阻止屏幕。
- 我已经阅读了一些关于 SO 的问题,我认为最相关的问题是 WinForms multithreading issue - 尽管我觉得对于这种情况来说这可能是矫枉过正。
如果您对我需要做些什么来实现两种表单的平滑渲染有任何想法,请告诉我。谢谢!
【问题讨论】:
-
你设置了timer的Interval属性吗?示例代码中未显示。
-
抱歉 - 在表单设计器中设置为 1000。
this->timerPrep->Interval = 1000; this->timerPrep->Tick += gcnew System::EventHandler(this, &GetReady::timerPrep_Tick);
标签: multithreading winforms c++-cli