anchor.diff:                  do! Async.SwitchToContext ctx
               })
   
  +type AsyncManualResetEvent() = 
  +    [<VolatileField>]
  +    let mutable _tcs = new TaskCompletionSource<bool>()
  +    
  +    member __.WaitAsync() = _tcs.Task |> Async.AwaitTask |> Async.Ignore
  +    
  +    member __.Reset() =
  +        let rec loop() =
  +            let tcs = _tcs
  +            if tcs.Task.IsCompleted &&
  +               Interlocked.CompareExchange(&_tcs, new TaskCompletionSource<bool>(), tcs) <> tcs then 
  +                loop()
  +        loop()
  +
  +    member __.Set() =
  +        let tcs = _tcs
  +        Task.Factory.StartNew(
  +            (fun s -> (box s :?> TaskCompletionSource<bool>).TrySetResult true),
  +            tcs, 
  +            CancellationToken.None, 
  +            TaskCreationOptions.PreferFairness, 
  +            TaskScheduler.Default) |> ignore
  +        tcs.Task.Wait()
  +
   type DocumentEventListener (events: IEvent<unit> list, delayMillis: uint16, update: CallInUIContext -> Async<unit>) =
       // Start an async loop on the UI thread that will execute the update action after the delay
       do if List.isEmpty events then invalidArg "events" "Events must be a non-empty list"
       let events = events |> List.reduce Event.merge
  +    let triggered = AsyncManualResetEvent()
  +    do events.Add (fun _ -> triggered.Set())
       let timer = DispatcherTimer(DispatcherPriority.ApplicationIdle, Interval = TimeSpan.FromMilliseconds (float delayMillis))
       let tokenSource = new CancellationTokenSource()
       let mutable disposed = false
  
positive.code: open System.Threading
  open System.Windows.Threading
  open FSharpVSPowerTools
  
  [<RequireQualifiedAccess>]
  module ViewChange =    
  
negative.code: 
         let computation =
             async { 
                 let mutable cts = new CancellationTokenSource()
                 startUpdate cts
  
                 while true do
                     //let e = events
                     do! triggered.WaitAsync()
                     triggered.Reset()
                     //Logging.logInfo <| fun _ -> "!!!!!!!!! awaited"
                     if not skipTimerDelay then
                         startNewTimer()
                         do! awaitPauseAfterChange()
                     cts.Cancel()
                     cts.Dispose()
                     cts <- new CancellationTokenSource()
                     startUpdate cts 
             }
         
         Async.StartInThreadPoolSafe (computation, tokenSource.Token)
  
  