我有一个有90个灰色数字的游戏,并且定期会有一些变成蓝色。(简化!)
现在我使用: 游戏 - >计时器 - >线程 - >着色数字 因为我想在着色时使用我的游戏。
代码:
some variables..
public FormHome()
{
InitializeComponent();
TEstrazione = new System.Timers.Timer(10000);
TEstrazione.AutoReset = false;
TEstrazione.Elapsed += timerEstrazioneElapsed;
TEstrazione.Start();
}
private void timerEstrazioneElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ThreadEstrazione = new Thread(cThread);
ThreadEstrazione.IsBackground = true;
ThreadEstrazione.Start();
}
private void cThread()
{
//other methods that change others controls..
coloring();
TEstrazione.Start();
}
void coloring()
{
for (int i = 0; i < 20; i++)//20 numbers to make colored
{
int num = *get random number*;
Label lbl;
lbl = (Label)panelNumembers.Controls["n" + num.ToString()];
if (lbl.InvokeRequired)
{
lbl.Invoke(new Action(coloring), new object[] { });
return;
}
lbl.BackColor = Color.DodgerBlue;
lbl.ForeColor = Color.Navy;
lbl.Refresh();
Thread.Sleep(800);
}
}
对不起,如果有些名字是意大利语,但我认为它们并不重要。
问题是当线程着色标签时,程序会锁定:我无法按下按钮甚至关闭它!
我认为这是一个线程安全问题,但我不知道其他方法
正如我所写,cThread中还有其他方法,都会更改控件。其中一个是:
void refreshLabel()
{
//here I always used one of the controls for the InvokeRequired
because in some cases I have so many and if I do the InvokeRequired
for each control becomes too long the code
if (label1.InvokeRequired)
{
ne.Invoke(new Action(refreshLabel), new object[] { });
return;
}
label1.Text = "xxxxx";
label1.Refresh();
label2.Text = "xxxxxxxxxxxxxxxx";
label2.Refresh();
}
总之,我有很多cThread启动的方法可以改变很多控件,有一种方法可以让线程安全而不会拉伸太多的代码吗?
我为英语道歉,但我是意大利语,并不容易用另一种语言解释问题。
答案 0 :(得分:0)
我正在使用我女朋友的笔记本电脑,所以我会编辑我的答案并尽快给你一个更好的答案。出现问题是因为大多数执行都在UI线程中。你应该在后台执行你的大部分执行。当您想要更新UI时,您需要将上下文更改为UI线程(仅更新!)。
将着色更改为:
void coloring()
{
for (int i = 0; i < 20; i++)//20 numbers to make colored
{
int num = *get random number*;
Label lbl;
lbl = (Label)panelNumembers.Controls["n" + num.ToString()];
var updateUI = new Action(() => {
lbl.BackColor = Color.DodgerBlue;
lbl.ForeColor = Color.Navy;
lbl.Refresh();
});
if (lbl.InvokeRequired)
{
Invoke(updateUI);
}
else
{
updateUI();
}
Thread.Sleep(800);
}
如果您的代码中没有其他阻止操作,那么这可能会起作用