title: Waiting for database rows to load using TableDependency and F#
body: <p>I've got an F# project that loads some files to an outside subsystem and then uses <a href="https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency" rel="nofollow noreferrer">Table Dependency</a> to wait for some rows to be added to a table as a side effect.</p>
  
  <p>Table Dependency is used in the type below to watch for the db changes.  It fires a custom event when a row is added/changed/whatever: </p>
  
  <pre class="lang-ml prettyprint-override"><code>// just using this type for the RecordChangedEvent to marshal the id we want into something
  type AccountLoaded() = 
      let mutable someId = ""
  
      // this property name matches the name of the table column (SomeId)
      member this.SomeId 
          with get () = someId
          and set (value) = someId &lt;- value
  
  // AccountLoadWatcher
  type AccountLoadWatcher() = 
      let mutable _tableDependency = null
      let event = new Event&lt;_&gt;()
  
      interface IDisposable with
          member this.Dispose() = 
              _tableDependency.Stop()
              _tableDependency.Dispose()
  
      // custom event we can send when an account is loaded
  
      [&lt;CLIEvent&gt;]
      member this.AccountLoaded = event.Publish
  
      member private this.NotifyAccountLoaded(sender : RecordChangedEventArgs&lt;AccountLoaded&gt;) = 
          let accountLoaded = sender.Entity
          event.Trigger(accountLoaded.SomeId)
  
      member this.Watch() = 
          _tableDependency &lt;- DbLib.getTableDependency "dbo" "AccountTable" 
                                  null
          _tableDependency.OnChanged.Add(this.NotifyAccountLoaded)
          _tableDependency.Start()
  </code></pre>
  
  <p>What I want to do is take the above object and just wait for all the rows with ids I care about to be loaded. What I have so far is:</p>
  
  <pre><code>let waitForRows(csvFileRows) =
    let idsToWaitFor = parseUniqueIdsFromAllRows csvFileRows
  
    let mutable collected = Set.empty
    let isInSet id = Set.contains id idsToWaitFor
    let notDone = not &lt;| (Set.difference idsToWaitFor collected = Set.empty)
    let accountLoadedHandler id = 
        collected &lt;- collected.Add id
        printfn "Id loaded %s, waiting for %A\n" id (Set.difference idsToWaitFor collected)
    loadToSubsystem csvFileRows |&gt; ignore
  
    // wait for all the watcher events; filtering each event object for ids we care about
       watcher.AccountLoaded
             |&gt; Observable.takeWhile (fun _ -&gt; notDone) 
             |&gt; Observable.filter (fun e -&gt; isInSet e) 
             |&gt; Observable.subscribe accountLoadedHandler
             |&gt; ignore
  
    doMoreWork()
  </code></pre>
  
  <p>but that just continues to doMoreWork without waiting for all the events i need above.</p>
  
  <p>Do I need to use a task or async?  F# Agents?</p>