多线程的问题,按钮的CD
private void pictureBox1_MouseUp(object sender, MouseEventArgs e) //鼠标释放,在当前坐标放置一个炮台
{
thread = new Thread(btn_cd);
thread.IsBackground = true;
MyTank = new Tank(type, poi.X, poi.Y);
if (type != 0&&Map[poi.X,poi.Y]==0&&money-MyTank.Price>0)
{
Map[poi.X, poi.Y] = 1;
MyTanks.Add(MyTank);
pictureBox1.Invalidate();
money = money - MyTank.Price;
textBox1.Text = Convert.ToString(money);
switch (type)
{
case 1: btn_tank1.Enabled = false; break;
case 2: btn_tank2.Enabled = false; break;
}
type_cd = type;
thread.Start();
}
type = 0;
}
private void btn_cd()
{
lock (this)
{
int i;
for (i = 1; i < 6; i++)
{
switch (type_cd)
{
case 1: btn_tank1.Text = Convert.ToString(i); break;
case 2: btn_tank2.Text = Convert.ToString(i); break;
}
Thread.Sleep(1000);
if (i == 5)
switch (type_cd)
{
case 1: btn_tank1.Enabled = true; btn_tank1.Text = ""; thread.Abort(); break;
case 2: btn_tank2.Enabled = true; btn_tank2.Text = ""; thread.Abort(); break;
}
}
}
}
功能:按下这个按钮实现5秒CD
点第一个按钮在它CD期间点第二个按钮就会出问题,是不是每次MOUSEUP会NEW一个线程,但是都是进入同一个btn_cd这个方法?另外我lock之后不是应该在一个线程结束之前不进入这个方法么?
该如何现在同时点击进入CD状态也不出问题,总不能一个按钮写个方法吧...
--------------------编程问答-------------------- 可以使用threadstart委托创建次线程等待。。 --------------------编程问答-------------------- 你本身程序就有问题。在线程里边去更改控件的属性值,当然会出错。
http://blog.csdn.net/yaoohfox/article/details/4019474
你去这里边看下,有解决多线程操作控件的 --------------------编程问答-------------------- 再多嘴一句,你的程序写得好烂。 --------------------编程问答--------------------
private void btn_cd()
{
lock (this)
{
int i;
for (i = 1; i < 6; i++)
{
this.Invoke((Action<int>)delegate(int j)
{
switch (type_cd)
{
case 1: btn_tank1.Text = Convert.ToString(j); break;
case 2: btn_tank2.Text = Convert.ToString(j); break;
}
Thread.Sleep(1000);
if (j == 5)
switch (type_cd)
{
case 1: btn_tank1.Enabled = true; btn_tank1.Text = ""; thread.Abort(); break;
case 2: btn_tank2.Enabled = true; btn_tank2.Text = ""; thread.Abort(); break;
}
}, j);
}
}
}
跨线程操作控件用Invoke --------------------编程问答--------------------
private void btn_cd()
{
lock (this)
{
int i;
for (i = 1; i < 6; i++)
{
this.Invoke((Action<int>)delegate(int j)
{
switch (type_cd)
{
case 1: btn_tank1.Text = Convert.ToString(j); break;
case 2: btn_tank2.Text = Convert.ToString(j); break;
}
Thread.Sleep(1000);
if (j == 5)
switch (type_cd)
{
case 1: btn_tank1.Enabled = true; btn_tank1.Text = ""; thread.Abort(); break;
case 2: btn_tank2.Enabled = true; btn_tank2.Text = ""; thread.Abort(); break;
}
}, i);
}
}
}
下面的J改为I --------------------编程问答--------------------
哈哈,我自己也觉得有很多可以美化的地方,第一步只为完成能实现的功能,因为刚学不久 --------------------编程问答--------------------
有什么能改进的或者什么编程习惯需要改的还请指教,刚接触C#半学期,代码读的少,好多用法没见过 --------------------编程问答--------------------
谢谢你的回复,但还是没解决我的问题。跨线程上面有个回复给了个网址我已经看了。大概明白了。但是您给的代码也没法解决我的问题,我想实现N个按钮,不论什么时候只要不在CD状态,我点下去就会有5秒CD。这里我不知道该怎么写 --------------------编程问答-------------------- 虽然不知道你要的效果是怎么样的,但应该你的逻辑没弄明白。
是不是有多个按钮,每个都有cd状态?只要不是在cd的时候,这个按钮就可以点击? --------------------编程问答--------------------
不好意思,看MSDN还是没太明白加不加ThreadStart委托的区别。能帮我讲下么,或者给我贴个相关知识的网址我自己看,麻烦您了 --------------------编程问答--------------------
是的。 --------------------编程问答-------------------- 如果只以时间为基准,用Timer
如果是以逻辑(某个操作完成)为基准,用回调(事件) --------------------编程问答--------------------
可是如果我按钮多了不是得每个按钮是一个方法了么. --------------------编程问答-------------------- Button btn = sender as Button;
btn.Enabled = false;
Task.Factory.StartNew(() =>
{
int i = 5;
while (i >= 0)
{
Thread.Sleep(1000);
this.Invoke(new Action(() =>
{
btn.Text = i.ToString();
if (i == 0)
{
btn.Enabled = true;
}
}));
i--;
}
});
给你写了,你拖一堆按钮,每个的click事件都来调用这个方法。 --------------------编程问答-------------------- 然后你照着这种原理去做吧
补充:.NET技术 , C#