首先,在您的使用情況下,沒有必要爲async { }
塊。 Async.AwaitTask
returns an Async<'T>
,所以你的async { }
塊只是解開你得到的Async
對象,並立即重新包裝它。
現在我們已經擺脫了不必要的async
塊,讓我們看看你得到的類型,以及你想要想要的類型。你得到了一個Async<'a>
,並且你想要一個'a
類型的對象。查看available Async
functions,類型簽名如Async<'a> -> 'a
的那個是Async.RunSynchronously
。它有兩個可選參數,一個int
和CancellationToken
,但如果你離開了這些,你有你要找的函數簽名。果然,當你在看文檔事實證明,Async.RunSynchronously
是的F#等效的await
C#,這是你想要的。(但不完全)像C#的await
。 C#的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
這應該讓你找到你想要的。並注意,找出你需要的函數的函數簽名的技術,然後尋找具有該簽名的函數。它將在未來幫助很多。
更新:謝謝Tarmil在意見指出我的錯誤:Async.RunSynchronously
是不等同於C#的await
。它非常相似,但有一些重要的細節要注意,因爲RunSynchronously
會阻止當前線程。 (你不想它調用你的GUI線程。)
更新2:當你想等待一個異步的結果,而不阻塞當前線程,它通常是說是這樣一個模式的一部分:
- 調用一些異步操作
- 等待其結果是
- 我與那結果
東西寫的是p中的最佳途徑attern如下:上述
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
example也談到了一些關於Async.SwitchToContext
function,這可能是你想要閱讀的東西。但我不熟悉SynchronizationContext
s告訴你更多。
嘗試'返回! eventStore。 ...而不是'return eventStore。 ...'? – ildjarn
@ildjarn - 剛剛在那裏試過。不幸的是,它返回完全相同的結果,即'FSharpAsync