The below is a bit of test code to show what I'm trying to achieve. Copy-Paste straight into LP to run.
I want to be able to soft stop the query or if an error happens on a background thread also stop the query, and show the exception.
If a background thread throws (after 5sec in the example) then all is ok.
If I soft stop before 5 seconds. The awaiter remains and I get weird behaviour on next run.
I did think that if I could incorporate the QueryCancelToken that would help kill the awaiter on a soft close. But if that is a non option in F# Program then can you see another way ?
open System.Threading.Tasks
let tcs = TaskCompletionSource()
Task.Run(fun () -> //mimicking some background work on a thread I dont control
Thread.Sleep(5000) //arbitary delay for the purposes of this excersise
tcs.SetException(InvalidCastException()) //an exception has been caught so lets give it to the tcs
)
task {
let d = Util.KeepRunning(true) //keep the query running to make the soft stop available
try
do! tcs.Task //wait for any background thread to throw (or complete normally)
with e ->
d.Dispose() //background thread threw, so dispose of soft close and end the query
raise e //re throw the error so LP shows it in the Results
}
Comments
This feature isn't supported from F#. QueryCancelToken in C# is implemented as an instance member, and in F# the query ends up in a static method.
Got a workaround here then ?
The below is a bit of test code to show what I'm trying to achieve. Copy-Paste straight into LP to run.
I want to be able to soft stop the query or if an error happens on a background thread also stop the query, and show the exception.
If a background thread throws (after 5sec in the example) then all is ok.
If I soft stop before 5 seconds. The awaiter remains and I get weird behaviour on next run.
I did think that if I could incorporate the QueryCancelToken that would help kill the awaiter on a soft close. But if that is a non option in F# Program then can you see another way ?
open System.Threading.Tasks
let tcs = TaskCompletionSource()
Task.Run(fun () -> //mimicking some background work on a thread I dont control
Thread.Sleep(5000) //arbitary delay for the purposes of this excersise
tcs.SetException(InvalidCastException()) //an exception has been caught so lets give it to the tcs
)
task {
let d = Util.KeepRunning(true) //keep the query running to make the soft stop available
try
do! tcs.Task //wait for any background thread to throw (or complete normally)
with e ->
d.Dispose() //background thread threw, so dispose of soft close and end the query
raise e //re throw the error so LP shows it in the Results
}
If you set Util.NewProcess to true, it should prevent any residue from effecting subsequent runs.
Did think about that, but that also kills all state between executions. Will have to work with that for now.