views:

145

answers:

4

what I am getting at is something like OpenFileDialog.Show() method that returns after indefinite amount of time, only after user does something (presses Ok in this case). Well, I know that I can achieve similar things for dialog controls by subclassing from dialog, or form, or something like that. But what if I want to do it for something totally unrelated to dialogs, e.g. I want to write a method InputStringToTextbox() that will return only after the user has entered a legal string into a textbox on the form and pressed Enter.

I do have some basic exposure to the concepts of threads and C#'s BeginInvoke/EndInvoke stuff, but I don't quite understand how to apply these ideas to this specific situation.

A: 

The method you reference works because it calls a .NET API that doesn't return until the user event happens. You can do something similar.

John Saunders
Downvoter? Tell me what's wrong with this answer, and I may be able to fix it.
John Saunders
+2  A: 

You can just implement a method that waits for something to happen.

void MainMethod()
{
...
...
DoSomethingAndWait()
...

}

private void DoSomethingAndWait()
{
...
...
   while(!somethingHappened) //updated by other thread
   {
        Thread.Sleep(100) ;
   }
...
}
pablito
A: 

Assuming WinForms:

If you want to make sure that the UI doesn't hang, you need to make sure to call Application.DoEvents() in your wait loop. If you don't do that, the UI will freeze.

Brian Genisio
There are better ways to accomplish this. Application.DoEvents() can result in hard-to-debug reentrance issues.
Joel Coehoorn
Calling DoEvents() is dangerous, so if you use it, you should do it with care.
arbiter
Yes, I agree it can be difficult to work with. But, what is the alternative? @Joel mentioned that there are better ways... what are they? (Serious question... not trying to be argumentative) If you were to write your own blocking dialog box (for whatever reason), how do you keep the UI alive?
Brian Genisio
+4  A: 

If you need to block threads, refer to the ManualResetEvent and AutoResetEvent classes. These are basic synchronization types that don't come with the extra baggage of types like Monitor, and in fact, many of the .NET synchronization types are built on top of them.

Here is a short example demonstrating the use, for the context you provided.

static class ThreadEntryPoints
{
  public static Main()
  {
    ShowDialog();
  }

  public static Other_Main()
  {
    // ... do some work ...
    _event.Set();
  }

  private static ShowDialog()
  {
    // ... do some work ...
    _event.WaitOne(/* optionally set timeout */);
  }

  private static readonly ManualResetEvent _event = new ManualResetEvent(false);
}
Steve Guidi