简体   繁体   English

在 while() 循环中使用 ManualResetEvent()

[英]using ManualResetEvent() in while() loop

i have a question about my simply code:我有一个关于我的简单代码的问题:

 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, how to use ManualResetEvent is clear and simple, but why the line this.BeginInvoke(new Action(() => this.richTextBox1.AppendText("ok finished " + cont))); Weel,如何使用ManualResetEvent 很简单明了,但是为什么这行this.BeginInvoke(new Action(() => this.richTextBox1.AppendText("ok finished " + cont))); will be never executed?永远不会被执行? I can stop my thread (.Reset) and restart it (.Set), but when resett.WaitOne() became FALSE why my code don't jump to 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))); ? ?

thanks a lot.多谢。

I' not sure if I can see what you want with your code but you can do something like this:我不确定我是否可以通过代码看到您想要的内容,但您可以执行以下操作:

while (!resett.WaitOne(500))
{
}

and then have a third button to stop the loop as this:然后有第三个按钮来停止循环,如下所示:

private void button3_Click(object sender, EventArgs e)
{
  ResetEvt.Set();
}

The WaitOne() without argument blocks the current thread until the handler i set, but with an argument in milliseconds it returns after that time, but with false as long as the handler is not set.不带参数的 WaitOne() 会阻塞当前线程,直到我设置了处理程序,但在此之后返回一个以毫秒为单位的参数,但只要未设置处理程序,它就会返回 false。

ManualResetEvent.WaitOne() will never return false. ManualResetEvent.WaitOne()永远不会返回 false。 Read the documentation .阅读文档

ManualResetEvent is a simple signalling primitive. ManualResetEvent是一个简单的信令原语。 It only has two logical values - set, and not set.它只有两个逻辑值——set 和 not set。 When you WaitOne on an event that isn't set, it will block until the event is set.当您在未设置的事件上WaitOne时,它将阻塞,直到设置该事件。 That's it - WaitOne doesn't return a boolean indicating the state of the event - it will simply return only when the event is set.就是这样 - WaitOne不返回指示事件状态的布尔值 - 它只会在设置事件时返回。

The return value is used for the overloads that take timeouts.返回值用于需要超时的重载。 In that case, WaitOne will return false when the timeout expires, and true if the event was signalled in the meantime.在这种情况下, WaitOne将在超时到期时返回 false,如果在此期间发出了该事件的信号,则返回 true。

Multi-threading is hard - you don't want to guess around.多线程很难——你不想到处乱猜。 I'd strongly recommend going at the very least through an introductory text to multi-threading - http://www.albahari.com/threading/ is a great free resource that gives nice explanations that get you most of the way to at least understanding the issues you'll be facing.我强烈建议您至少阅读多线程的介绍性文本 - http://www.albahari.com/threading/是一个很棒的免费资源,它提供了很好的解释,至少可以让您在了解您将面临的问题。

In your case, it seems that what you're really looking for is a Timer .在您的情况下,您真正​​要寻找的似乎是Timer Or better, if you're waiting for some asynchronous event to happen, use asynchronous code - that avoids all the busy-looping, as well as the pointless Thread s.或者更好的是,如果您正在等待某个异步事件发生,请使用异步代码 - 避免所有繁忙循环以及无意义的Thread

There's other issues with your code as well.您的代码还有其他问题。 You might want to take your (working) code to CodeReview for a few pointers.您可能希望将您的(工作)代码带到 CodeReview 以获得一些提示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ManualResetEvent与while循环 - ManualResetEvent vs while loop 使用ManualResetEvent在内部等待 - Wait inside While with ManualResetEvent 使用 manualResetEvent 死锁 - c# - Deadlock using manualResetEvent - c# 在回调模拟设置上设置 ManualResetEvent 时出错 - Error while setting ManualResetEvent on callback mock setup 使用BackgroundWorker的ManualResetEvent:WaitOne()时当前线程忙吗? - ManualResetEvent with a BackgroundWorker : Current thread is busy while WaitOne()? ManualResetEvent在处于等待状态时会消耗cpu吗? - Will the ManualResetEvent consume cpu while it is in a wait state? 使用CountdownEvent和ManualResetEvent来控制ThreadPool中的线程 - Using CountdownEvent and ManualResetEvent to control threads in ThreadPool 在线程之间循环时退出/取消的技术:bool,ManualResetEvent或CancellationToken - Techniques for exiting / cancelling while loops across threads: bool, ManualResetEvent or CancellationToken 使用ManualResetEvent等待多个Image.ImageOpened事件 - Using ManualResetEvent to wait for multiple Image.ImageOpened events 为什么在WPF中使用ManualResetEvent和异步方法时会发生死锁? - Why does deadlock occur when using ManualResetEvent and asynchronous method in WPF?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM