タイムアウトと CancellationToken を指定して Async.RunSynchronously を呼び出すと、タイムアウト値が無視されるようです。CancellationToken で CancelAfter を呼び出すことでこれを回避できますが、理想的には、ワークフローで発生する例外、TimeOutExceptions と OperationCanceledExceptions を区別できるようにしたいと考えています。
以下のサンプルコードがこれを示していると思います。
open System
open System.Threading
let work =
async {
let endTime = DateTime.UtcNow.AddMilliseconds(100.0)
while DateTime.UtcNow < endTime do
do! Async.Sleep(10)
Console.WriteLine "working..."
raise ( Exception "worked for more than 100 millis" )
}
[<EntryPoint>]
let main argv =
try
Async.RunSynchronously(work, 50)
with
| e -> Console.WriteLine (e.GetType().Name + ": " + e.Message)
let cts = new CancellationTokenSource()
try
Async.RunSynchronously(work, 50, cts.Token)
with
| e -> Console.WriteLine (e.GetType().Name + ": " + e.Message)
cts.CancelAfter(80)
try
Async.RunSynchronously(work, 50, cts.Token)
with
| e -> Console.WriteLine (e.GetType().Name + ": " + e.Message)
Console.ReadKey(true) |> ignore
0
次の出力は、タイムアウトが最初のケース (CancelationToken が指定されていない場合) でのみ有効であることを示しています。
working...
working...
TimeoutException: The operation has timed out.
working...
working...
working...
working...
working...
working...
working...
Exception: worked for more than 100 millis
working...
working...
working...
working...
working...
working...
OperationCanceledException: The operation was canceled.
これは意図した動作ですか?私が求めている動作を取得する方法はありますか?
ありがとう!