は、私はこのスニペットを見つけた:F#と非同期のMonadicリトライロジック?
しかし、私だけではなく再試行機能を備えた、だけでなく、非同期で働いている、と私は適切にこのタイプを作るどのように私は思っていました。私はretryAsync
モナドの小さな断片を持っていますが、私は非同期計算の代わりに使っていますが、再試行論理が含まれています。 >Async<'c>
この式は、タイプ
Async<'a>
を持つことが期待されたが、:module Queue = let desc (nm : NamespaceManager) name = asyncRetry { let! exists = Async.FromBeginEnd(name, nm.BeginQueueExists, nm.EndQueueExists) let beginCreate = nm.BeginCreateQueue : string * AsyncCallback * obj -> IAsyncResult return! if exists then Async.FromBeginEnd(name, nm.BeginGetQueue, nm.EndGetQueue) else Async.FromBeginEnd(name, beginCreate, nm.EndCreateQueue) } let recv (client : MessageReceiver) timeout = let bRecv = client.BeginReceive : TimeSpan * AsyncCallback * obj -> IAsyncResult asyncRetry { let! res = Async.FromBeginEnd(timeout, bRecv, client.EndReceive) return res }
エラーは次のとおりです。
type AsyncRetryBuilder(retries) = member x.Return a = a // Enable 'return' member x.ReturnFrom a = x.Run a member x.Delay f = f // Gets wrapped body and returns it (as it is) // so that the body is passed to 'Run' member x.Bind expr f = async { let! tmp = expr return tmp } member x.Zero = failwith "Zero" member x.Run (f : unit -> Async<_>) : _ = let rec loop = function | 0, Some(ex) -> raise ex | n, _ -> try async { let! v = f() return v } with ex -> loop (n-1, Some(ex)) loop(retries, None) let asyncRetry = AsyncRetryBuilder(4)
消費コードは次のようです
? – Daniel
特定のエラーに関して、あなたの 'Bind'は、引数をタプル(' x.Bind expr f'の代わりに 'x.Bind(expr、f)'と書く)として引数を取るべきです。それがおそらく原因です。しかし、 'f'も全く使用していません。これは非常に疑わしい(あなたの' Return'は間違ったタイプです)。 –