5

F# の非同期ワークフローを理解しようとしていますが、本当に理解できない部分が 1 つあります。

次のコードは正常に動作します。

let asynWorkflow = async{
    let! result = Stream.TryOpenAsync(partition) |> Async.AwaitTask 
    return result
    } 

let stream = Async.RunSynchronously asynWorkflow
             |> fun openResult -> if openResult.Found then openResult.Stream else Stream(partition)

TryOpenAsync が型を返す非同期ワークフローを定義しますTask<StreamOpenResult>Async<StreamOpenResult>Async.AwaitTaskで変換します。(サイドクエスト: "Await"Task? await じゃなくて変換するだけですよね? Task.Wait とか await キーワードとか関係ないと思います)。で「待って」let!返します。ワークフローを開始するには、ワークフローを開始して結果を返す (バインドする) RunSynchronously を使用します。結果で、ストリームが見つかったかどうかを確認します。

しかし、今私の最初の質問に。TryOpenAsync 呼び出しを別の非同期計算でラップして、そのままにする必要があるのはなぜですか。(「待って」)それ?たとえば、次のコードは機能しません。

let asynWorkflow =  Stream.TryOpenAsync(partition) |> Async.AwaitTask  

let stream = Async.RunSynchronously asynWorkflow
             |> fun openResult -> if openResult.Found then openResult.Stream else Stream(partition)

AwaitTask はそれを開始する必要があると思いましAsync<T>RunSynchronously。次に、結果を使用します。何が恋しいですか?

私の 2 番目の質問は、なぜ「Async.Let!」があるのか​​ということです。利用可能な機能? うまくいかないか、うまくいかないためか、次のコードでうまくいかないのはなぜですか?

let ``let!`` task = async{
    let! result = task |> Async.AwaitTask 
   return result
   } 

let stream = Async.RunSynchronously ( ``let!`` (Stream.TryOpenAsync(partition))  )
         |> fun openResult -> if openResult.Found then openResult.Stream else Stream(partition)

TryOpenAsync をパラメーターとして挿入するだけですが、機能しません。うまくいかないと言うことは、FSI全体がハングアップすることを意味します。したがって、それは私の非同期/「待機」と関係があります。

- - アップデート:

FSI での作業コードの結果:

>

Real: 00:00:00.051, CPU: 00:00:00.031, GC gen0: 0, gen1: 0, gen2: 0
val asynWorkflow : Async<StreamOpenResult>
val stream : Stream

FSI でコードが機能しない結果:

>

そして、FSI では何も実行できなくなりました

--- 更新 2

ストリームストーンを使用しています。C# の例: https://github.com/yevhen/Streamstone/blob/master/Source/Example/Scenarios/S04_Write_to_stream.cs

ここで Stream.TryOpenAsync: https://github.com/yevhen/Streamstone/blob/master/Source/Streamstone/Stream.Api.cs#L192

4

3 に答える 3

3

別の質問であなたの質問に答えたいわけではありませんが、とにかくこのようなコードを実行しているのはなぜですか? それはそれを理解するのに役立つかもしれません。それだけではない理由:

let asyncWorkflow = async {
    let! result = Stream.TryOpenAsync(partition) |> Async.AwaitTask 
    if result.Found then return openResult.Stream else return Stream(partition) }

すぐに呼び出すためだけに非同期ワークフローを作成してもほとんど意味がありません。これは aRunSynchronouslyを呼び出すのと似ています。ワークフローが戻るまで現在のスレッドをブロックするだけです。.ResultTask

于 2017-11-16T15:50:18.410 に答える