我在下面有这个button5功能。我想要的是当用户想要在按钮5之后点击button1时,button5中的while循环应该中断,因为现在选择是1. Choice
是一个全局变量,在开始时设置为零。当button5函数运行时,click1函数在点击时不会被调用。如何解决这个问题?
This is the Answer Thanks Everyone For the Help!!
private Thread demoThread = null;
delegate void SetTextCallback(string text);
private void button1_Click(object sender, EventArgs e)
{
choice = 1;
System.Console.WriteLine(choice);
}
private void button5_Click(object sender, EventArgs e)
{
//button1.Enabled = false;
button5.Visible = false;
panel2.Visible = true;
panel1.Visible = true;
panel3.Visible = true;
label2.Visible = true;
button1.Visible = true;
button2.Visible = true;
button3.Visible = true;
button4.Visible = true;
this.demoThread = new Thread(new ThreadStart(this.StartForLoop));
this.demoThread.Start();
}
private void StartForLoop()
{
while (choice != 1 || choice != 2 || choice != 3)
{
if (choice == 1 )
{
choice = 1;
break;
}
if (choice == 2)
{
choice = 2;
break;
}
if (choice == 3)
{
choice = 3;
break;
}
Application.DoEvents();
}
System.Console.WriteLine("AAA");
if (choice == 3)//why
{
}
if (choice == 1)//true
{
System.Console.WriteLine("label");
this.SetText("Does the animal lay eggs?");
}
if (choice == 2)//false
{
}
}
答案 0 :(得分:3)
这是一个错误的概念。永远不要使用Application.DoEvents();
,这是一个黑客攻击。它没有解决你的任何问题。
你在Button5_Click中不需要while循环。该循环中的所有内容都可以通过其他单击处理程序中的代码来处理。
您的问题可能由state machine解决。这看起来很复杂,但它不是。尝试尽可能简单地实现它,并在遇到问题时提出另一个问题。
答案 1 :(得分:1)
你遇到Thread的问题,问题是你编程Thread忙于你的button5循环,直到它完成处理button5代码,你的线程将不会注意更多的东西。
要解决此问题,您必须在新线程中运行while循环,如下所示:
Thread t = new Thread (new ThreadStart(delegate(){
//while goes here along with the if's...
}));
t.Start();
在button1中,更改全局变量的值时 现在可以知道在button5中启动的线程内部的代码 你的改变和行为相应。
另外要注意以下事项,因为选择是一个全局变量 它现在可以通过两个线程同时访问程序线程 和你的新线程,因为这确保你访问选择变量 使用互斥锁,在c#中,您可以访问线程共享变量,如下所示:
//declare this next to your choice variable.
Object mux_choice = new Object();
lock(mux_choice){
//changing choice here is thread safe.
}
由于选择似乎是值类型,因此您必须创建一个对象来表示对值类型变量(http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx)的访问。
您在C#中有更多关于线程的信息: http://www.albahari.com/threading/
注意:确保在使用它的任何地方保护选择变量。
另外,根据您的评论,我假设您要修改表单控件 属性,如label2.Text =“...”因此,如果你这样做,你将面临交叉线程异常。要修改Controls属性,必须调用Invoke方法,该方法调用UI线程中的更改,如下所示:
label2.Invoke((MethodInvoker)(() => label2.Text = "some text"));
根据.NET框架版本,这里是与.NET 2.0兼容的代码:
label2.Invoke(new MethodInvoker(delegate(){ label2.Text = "some text"; }));
问候。
答案 2 :(得分:1)
最好的方法是为每个循环运行一个到另一个线程,这样就不会打扰表单的UI。 用户可以轻松点击按钮1。
只是为了基本的想法:
private void button5_Click(object sender, EventArgs e)
{
button5.Visible = false;
panel2.Visible = true;
panel1.Visible = true;
panel3.Visible = true;
label2.Visible = true;
button1.Visible = true;
button2.Visible = true;
button3.Visible = true;
button4.Visible = true;
Thread thread = new Thread(new ThreadStart(StartForLoop));
thread.Start();
}
public void StartForLoop()
{
while (choice != 1 || choice != 2 || choice != 3)
{
if (choice == 1 || choice == 2 || choice == 3)
{
choice = 1000;
break;
}
Application.DoEvents();
}
if(choice==3)//why
{
}
if(choice==1)//true
{
label2.Text = "asdasd";
}
if(choice==2)//false
{
}
}
PS:更好地实现锁定选择