我对我的简单代码有疑问:
public partial class Form1 : Form {
ManualResetEvent ResetEvt = new ManualResetEvent(false);
Thread t1;
public Form1() {
InitializeComponent();
}
//create
private void button1_Click(object sender, EventArgs e) {
t1 = new Thread(new ParameterizedThreadStart((reset) => {
int cont = 0;
var resett = reset as ManualResetEvent;
Thread.CurrentThread.IsBackground = true;
while (resett.WaitOne()) {
try {
this.BeginInvoke(new Action(() => this.richTextBox1.AppendText("Ciao " + cont)));
cont++;
Thread.Sleep(500);
}
catch (Exception) {
MessageBox.Show("END");
}
}
this.BeginInvoke(new Action(() => this.richTextBox1.AppendText("ok finished " + cont)));
}));
}
private void button2_Click(object sender, EventArgs e) {
try {
t1.Start(this.ResetEvt);
}
catch (Exception) {
}
}
private void button3_Click(object sender, EventArgs e) {
this.ResetEvt.Reset();
}
private void button4_Click(object sender, EventArgs e) {
ResetEvt.Set();
}
private void button5_Click(object sender, EventArgs e) {
// ??? ho can stop while? and continue execution?
}
}
Weel,如何使用ManualResetEvent既清晰又简单,但为什么要行this.BeginInvoke(new Action(() => this.richTextBox1.AppendText("ok finished " + cont)));
永远不会被执行?我可以停止我的线程(.Reset)并重新启动它(.Set),但是当resett.WaitOne()变为FALSE时为什么我的代码不会跳转到this.BeginInvoke(new Action(() => this.richTextBox1.AppendText("ok finished " + cont)));
?
非常感谢。
答案 0 :(得分:1)
我不确定我是否可以通过您的代码查看您想要的内容,但您可以执行以下操作:
while (!resett.WaitOne(500))
{
}
然后有第三个按钮来停止循环:
private void button3_Click(object sender, EventArgs e)
{
ResetEvt.Set();
}
不带参数的WaitOne()会阻塞当前线程,直到我设置的处理程序,但是在该时间之后返回的参数以毫秒为单位,但只要处理程序未设置就为false。
答案 1 :(得分:0)
ManualResetEvent.WaitOne()
永远不会返回false。阅读documentation。
ManualResetEvent
是一个简单的信令原语。它只有两个逻辑值 - 设置,而不是设置。当您WaitOne
对未设置的事件进行处理时,它将一直阻止,直到设置了该事件。就是这样 - WaitOne
不返回表示事件状态的布尔值 - 它只会在事件设置时返回。
返回值用于超时的重载。在这种情况下,WaitOne
将在超时到期时返回false,如果事件在此期间发出信号,则返回true。
多线程很难 - 你不想猜测。我强烈建议至少通过多线程的介绍性文本 - http://www.albahari.com/threading/是一个很好的免费资源,可以提供很好的解释,让你最好的方式来至少理解你将要成为的问题面对。
在你的情况下,你真正想要的是Timer
。或者更好的是,如果您正在等待某个异步事件发生,请使用异步代码 - 这样可以避免所有繁忙的循环,以及无意义的Thread
。
您的代码还存在其他问题。您可能希望将(工作)代码带到CodeReview以获取一些指示。