在 F# 中使用 TaskCompletionSource 以在 .NET 库中使用
Using TaskCompletionSource in F# for use in a .NET library
考虑以下因素
type MyClass () =
member x.ReadStreamAsync(stream:Stream) =
async {
let tcs = new TaskCompletionSource<int>()
let buffer = Array.create 2048 0uy
let! bytesReadCount = stream.ReadAsync(buffer, 0, buffer.Length) |> Async.AwaitTask
if bytesReadCount > 0 then
for i in 0..bytesReadCount do
if buffer.[i] = 10uy then
tcs.SetResult(i)
// Omitted more code to handle the case if 10uy is not found..
return tcs.Task
}
代码从流中读取直到遇到特定字符(由字节值表示),此时方法返回的任务完成。
DoSomethingAsync
的函数签名是 unit -> Async<Task<int>>
,但我希望它是 unit -> Task<int>
这样它可以在 .NET 中更普遍地使用。
这可以在 F# 中使用异步表达式完成,还是我可以更多地依赖 .NET 的 Task
结构?
鉴于您实际上并未使用示例中的任何内容的异步工作流,最简单的解决方案是完全放弃它:
member x.DoSomethingAsync() =
let tcs = new TaskCompletionSource<int>()
Task.Delay(100).Wait()
tcs.SetResult(10)
tcs.Task
DoSomethingAsync
的实现类型为 unit -> Task<int>
。
我不清楚你到底想做什么,但你为什么不做下面的事情呢?
member x.DoSomethingAsync() =
async {
do! Async.Sleep 100
return 10 } |> Async.StartAsTask
此实现还具有类型 unit -> Task<int>
。
根据更新后的问题,这里有一个方法:
member x.DoSomethingAsync(stream:Stream) =
async {
let buffer = Array.create 2048 0uy
let! bytesReadCount =
stream.ReadAsync(buffer, 0, buffer.Length) |> Async.AwaitTask
if bytesReadCount > 0
then
let res =
[0..bytesReadCount]
|> List.tryFind (fun i -> buffer.[i] = 10uy)
return defaultArg res -1
else return -1
}
|> Async.StartAsTask
DoSomethingAsync
函数的类型为 Stream -> System.Task<int>
。我不知道在 else
情况下该怎么做,所以我只放了 -1
,但我相信你可以用更正确的东西替换它。
考虑以下因素
type MyClass () =
member x.ReadStreamAsync(stream:Stream) =
async {
let tcs = new TaskCompletionSource<int>()
let buffer = Array.create 2048 0uy
let! bytesReadCount = stream.ReadAsync(buffer, 0, buffer.Length) |> Async.AwaitTask
if bytesReadCount > 0 then
for i in 0..bytesReadCount do
if buffer.[i] = 10uy then
tcs.SetResult(i)
// Omitted more code to handle the case if 10uy is not found..
return tcs.Task
}
代码从流中读取直到遇到特定字符(由字节值表示),此时方法返回的任务完成。
DoSomethingAsync
的函数签名是 unit -> Async<Task<int>>
,但我希望它是 unit -> Task<int>
这样它可以在 .NET 中更普遍地使用。
这可以在 F# 中使用异步表达式完成,还是我可以更多地依赖 .NET 的 Task
结构?
鉴于您实际上并未使用示例中的任何内容的异步工作流,最简单的解决方案是完全放弃它:
member x.DoSomethingAsync() =
let tcs = new TaskCompletionSource<int>()
Task.Delay(100).Wait()
tcs.SetResult(10)
tcs.Task
DoSomethingAsync
的实现类型为 unit -> Task<int>
。
我不清楚你到底想做什么,但你为什么不做下面的事情呢?
member x.DoSomethingAsync() =
async {
do! Async.Sleep 100
return 10 } |> Async.StartAsTask
此实现还具有类型 unit -> Task<int>
。
根据更新后的问题,这里有一个方法:
member x.DoSomethingAsync(stream:Stream) =
async {
let buffer = Array.create 2048 0uy
let! bytesReadCount =
stream.ReadAsync(buffer, 0, buffer.Length) |> Async.AwaitTask
if bytesReadCount > 0
then
let res =
[0..bytesReadCount]
|> List.tryFind (fun i -> buffer.[i] = 10uy)
return defaultArg res -1
else return -1
}
|> Async.StartAsTask
DoSomethingAsync
函数的类型为 Stream -> System.Task<int>
。我不知道在 else
情况下该怎么做,所以我只放了 -1
,但我相信你可以用更正确的东西替换它。