This comes up a lot, so someone (Tomas) invented Event.guard:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    module Event = 
        let guard f (e:IEvent<'Del, 'Args>) =  
            let e = Event.map id e 
            { new obj() with
                  member x.ToString() = ""
              interface IEvent<'Args>  
              interface IDelegateEvent<Handler<'Args>> with 
                  member x.AddHandler(d) = e.AddHandler(d); f()
                  member x.RemoveHandler(d) = e.RemoveHandler(d) 
              interface System.IObservable<'Args> with 
                  member x.Subscribe(observer) =  
                      let rm = e.Subscribe(observer) 
                      f() 
                      rm } 

so that rather than

1
2
   somethingThatStartsAnAsyncThatEventuallyFires()
   Async.AwaitEvent(TheEvent)

which is subject to the race you've seen, you can do

1
   Async.AwaitEvent( Event.guard (fun () -> somethingThat...() ) TheEvent )

which subscribes first, then runs the lambda, and then returns the event you can await. That is, Event.guard takes a lambda and an event, and returns that same event except it will run the lambda after subscribing so that you never 'miss' the event if the lambda may provoke it.

By on 11/25/2010 10:14 AM ()

Hi,

don't know if this is really the issue but it might be.

I suggest stop using the events but working with System.Threading.ManualResetEvent to check states. Or - and that might be even better - use System.Threading.Task to do this stuff (in C# or F# - no matter)

By on 11/25/2010 3:58 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper