asynchronous - Async.TryCancelled doesn't work with Async.RunSynchronously -


i try create agent updates ui based on user interaction. if user clicks on button, gui should refreshed. preparation of model takes long time, desirable if user clicks on other button, preparation cancelled , new 1 started.

what have far:

open system.threading type private refreshmsg =      | refreshmsg of asyncreplychannel<cancellationtokensource>  type refresheragent() =       let mutable cancel : cancellationtokensource = null      let dosomemodelcomputation =         async {            printfn "start %a"           do! async.sleep(1000)           printfn "middle %a"           do! async.sleep(1000)           printfn "end %a"         }     let mbox =          mailboxprocessor.start(fun mbx ->             let rec loop () = async {                 let! msg = mbx.receive()                 match msg                 | refreshmsg(chnl) ->                     let cancelsrc = new cancellationtokensource()                     chnl.reply(cancelsrc)                     let update = async {                                     do! dosomemodelcomputation 1                                     do! dosomemodelcomputation 2                                     //do! updateui // not important                                  }                     let cupdate = async.trycancelled(update, (fun c -> printfn "refresh cancelled"))                     async.runsynchronously(cupdate, -1, cancelsrc.token)                     printfn "loop()"                     return! loop()             }             loop ())             mbox.error.add(fun exn -> printfn "error in refresher: %a" exn)     member x.refresh() =          if cancel <> null             // don't handle whether previous computation finished             // cancel it; might improved             cancel.cancel()             cancel.dispose()         cancel <- mbox.postandreply(fun reply -> refreshmsg(reply))         printfn "x.refresh end"  //sample   let agent = refresheragent() agent.refresh() system.threading.thread.sleep(1500) agent.refresh() 

i return cancellationtokensource each request , store in mutable variable (the x.refresh() thread safe, called on ui thread). if refresh() called first time, cancellation source returned. if refresh() called second time, call cancel should abort async task run through async.runsynchronously.

however, exception raised. output sample

x.refresh end start 1 middle 1 end 1 refresh cancelled error in refresher: system.operationcanceledexception: operation canceled.    @ microsoft.fsharp.control.asyncbuilderimpl.commit[a](result`1 res) 

now think this, might make sense, because thread on agent runs, interrputed, right? but, how achieve desired behaviour?


i need cancel async workflow inside agent, agent can continue consuming new messages. why use mailbox processor? cause guaranteed 1 thread trying create ui model, save resources.

let's suppose create ui model downloading data several web services, that's why use async call. when user changes combo , select other option, want stop querying webservices (= cancel async calls) old value , want create new model base od web services call new value.

any suggestion can use instead of solution , solve problem, welcome.

i have difficulties in trying understand want achieve. maybe not matter - error says workflow executing runsynchronously canceled (runsynchronously throw exception) - can wrap call try-match block , ignore oc-exception

a better option might refactor cupdate , try-match inside of - can bring in trycancelled if catch oc-exceptions directly ;)

let update =     async {       try          do! dosomemodelcomputation 1          do! dosomemodelcomputation 2             | :? operationcanceledexception ->             printfn "refresh cancelled"    } async.runsynchronously(update, -1, cancelsrc.token) 

but still don't part why want synchronously


Comments

Popular posts from this blog

delphi - How to convert bitmaps to video? -

jasper reports - Fixed header in Excel using JasperReports -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -