10

I would like to create some method to be used in a generic way, were it would block (unless a certain timeout expires) until a given condition is met.

The usage in code would be something similar to:

WaitUntil( condition );

I have tried implementing it using a While ( .. ) loop, however this seems like a waste.

In current implementation, i am initializing a 'one-off' timer that expires at TIMEOUT. I am running a while loop, and checking if the timer has timed out or not, throwing an exception if it did.

Are there any simple yet effective techniques for implementing such a method ?

diggingforfire
  • 3,359
  • 1
  • 23
  • 33
lysergic-acid
  • 19,570
  • 21
  • 109
  • 218
  • I would look into delegates and events – Joe Jan 07 '12 at 16:56
  • 3
    Mutex,Semaphore,ManualResetEvent,AutoResetEvent,CountdownEvent etc. Look at the System.Threading namespace – L.B Jan 07 '12 at 17:04
  • 3
    Saying more technically you want to synchronize on something. Operating system provides mechanisms which allow to avoid busy waiting in while loop. Yoy have number of options: semaphore, critical section, manual/auto reset event and more. To choose one you should say what is the condiition you're waiting for. One generic function for synchronization is WaitForSingleObject. – pkmiec Jan 07 '12 at 17:08
  • The condition should be a parameter of the synchronization method. Meaning that i would like to construct a mechanism to be used all across different scenarios, where the code cannot proceed unless some condition was met. – lysergic-acid Jan 07 '12 at 17:13
  • I think that fully generic solution - taking only simple delgate that checks the condition - is not possible without busy waiting. Busy waiting avoidance is about giving notification on the state change from the one, that knows when it will happen. Your delegate must really wait for some kind of notification, not just "check condition". – pkmiec Jan 07 '12 at 17:32

2 Answers2

10

Have a look at Albahari's threading article, especially the basic synchronization part and the ManualResetEvent and AutoResetEvent. This will give you a good idea about signalling constructs in .NET.

diggingforfire
  • 3,359
  • 1
  • 23
  • 33
4

Blocking for a condition can work (I tend to use Monitor for that personally), however, in most cases I would advise coding in a more async way here, meaning: rather than waiting, you register some kind of callback to occur when the condition happens. This could be via an event, or more recently a Task with continuation (ContinueWith). In c# 5 this is further extended with the "await" metaphor that makes this transparent, I.e.

var foo = StartSomeWork();
...
var result = await foo;
Console.WriteLine(result);

This looks like it is blocking at the "await" - but it is in fact the exact opposite (assuming the task isn't already complete); this registers a continuation that is invoked when the data becomes available, most likely on a different thread.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • The only problem with this code is: We are using .NET 3.5, and version 5 is not out yet :) does the CTP work on 3.5? ( i dont think so ). – lysergic-acid Jan 07 '12 at 23:04
  • @liortal you can use ContinueWith on 4.0; I wouldn't use the CTP for production code – Marc Gravell Jan 07 '12 at 23:36
  • @liortal then the TPL is no-go, but the general approach of callbacks is still fine – Marc Gravell Jan 07 '12 at 23:50
  • How do i block until the callback is fired? (or not fired). My context is an app that runs my method as a "plugin" and expects the call to return. I do not want too much coordination logic going on, and so i would like all the callbacks/event handling to occur from within my running code and not to return to the main app waiting for a callback. – lysergic-acid Jan 08 '12 at 00:06
  • 1
    @liortal then a callback may not be your bet option! It all depends on the context, which is not in the question. – Marc Gravell Jan 08 '12 at 00:12