Search code examples
f#event-handlingtask

How do I subscribe to an event using task expressions?


I have a function doSomething : EventArgs -> Task<Unit>, an event source Source and an event Source.OnChanged. How can I subscribe doSomething to Source.OnChanged? In C# we would use an async event handler but this doesn't seem possible in F#.


Solution

  • I think this does what you want:

    let source = Source()
    source.OnChanged.Add(
        doSomething
            >> Async.AwaitTask
            >> Async.StartImmediate)
    

    Full example:

    type Source() =
    
        let event = Event<int>()
    
        [<CLIEvent>]
        member _.OnChanged = event.Publish
    
        member _.Trigger(arg) = event.Trigger(arg)
    
    let doSomething arg =
        task {
            printfn $"Doing something with {arg}"
        }
    
    let source = Source()
    source.OnChanged.Add(
        doSomething
            >> Async.AwaitTask
            >> Async.StartImmediate)
    
    source.Trigger(0)
    

    Output is:

    Doing something with 0
    

    See this similar SO question for more details.