Properly expecting in F # the C # async method with the return type Task <T>

I would like to be able to use the C # library from F #. It was basically pretty simple. However, if I try to call a function that returns Task<T>, I cannot get the return value.

So, I have a C # method with the following definition:

public async Task<TEvent> ReadEventAsync<TEvent>(string streamName, int position) where TEvent: class

And I am trying to use this method from F # as follows:

let readEventFromEventStore<'a when 'a : not struct> (eventStore:IEventStoreRepository) (streamName:string) (position:int) = 
     async {
            return eventStore.ReadEventAsync(streamName, position) 
            |> Async.AwaitTask
            }

I partially apply this function with the instance IEventStoreRepositoryand the name of the stream from which I want to receive the event:

let readEvent = readEventFromEventStore eventStore streamName

Then, finally, I apply the remaining parameter:

let event = readEvent StreamPosition.Start

When I get the value event, it is FSharpAsync<object>, and not Tfrom Task<T>, which I expected.

F # async, # Task<T> T?

+9
2

, async { }. Async.AwaitTask Async<'T>, async { } Async .

, async , , , , . Async<'a> 'a. Async Async<'a> → 'a Async.RunSynchronously. , int CancellationToken, , . , , , , Async.RunSynchronously F # # await, , . ( ) # await. # await - , async , F # Async.RunSynchronously async , , async . .

let readEventFromEventStore<'a when 'a : not struct> (eventStore:IEventStoreRepository) (streamName:string) (position:int) =
    eventStore.ReadEventAsync(streamName, position) 
    |> Async.AwaitTask
    |> Async.RunSynchronously

, . , , . .

: , , : Async.RunSynchronously # await. , , , RunSynchronously . ( GUI.)

2: , , , :

  1. -

:

let equivalentOfAwait () =
    async {
        let! result = someAsyncOperation()
        doSomethingWith result
    }

, doSomethingWith unit, - . , :

let equivalentOfAwait () =
    async {
        let! result = someAsyncOperation()
        let value = someCalculationWith result
        return value
    }

, :

let equivalentOfAwait () =
    async {
        let! result = someAsyncOperation()
        return (someCalculationWith result)
    }

, someCalculationWith . , - - :

let equivalentOfAwait () =
    async {
        let! result1 = someAsyncOperation()
        let! result2 = nextOperationWith result1
        let! result3 = penultimateOperationWith result2
        let! finalResult = finalOperationWith result3
        return finalResult
    }

let! return return! , :

let equivalentOfAwait () =
    async {
        let! result1 = someAsyncOperation()
        let! result2 = nextOperationWith result1
        let! result3 = penultimateOperationWith result2
        return! (finalOperationWith result3)
    }

Async<'T>, 'T async . , Async.RunSynchronously , Async.Start (Start, StartImmediate, StartAsTask, StartWithContinuations ..). Async.StartImmediate Async.SwitchToContext, , , . SynchronizationContext .

+13

Source: https://habr.com/ru/post/1014225/


All Articles