Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在F#中使用TaskCompletionSource以在.NET库中使用_F# - Fatal编程技术网

在F#中使用TaskCompletionSource以在.NET库中使用

在F#中使用TaskCompletionSource以在.NET库中使用,f#,F#,考虑到以下几点: type MyClass () = member x.ReadStreamAsync(stream:Stream) = async { let tcs = new TaskCompletionSource<int>() let buffer = Array.create 2048 0uy let! bytesReadCount = stream.ReadAsync(bu

考虑到以下几点:

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
        }
键入MyClass()=
成员x.ReadStreamAsync(流:流)=
异步的{
让tcs=new TaskCompletionSource()
让buffer=Array.create 2048 0uy
let!bytesReadCount=stream.ReadAsync(buffer,0,buffer.Length)|>Async.waitTask
如果ByteReadCount>0,则
对于0中的i..ByteReadCount do
如果缓冲区[i]=10uy,则
tcs.SetResult(一)
//如果未找到10uy,则省略更多代码来处理此情况。。
返回tcs.Task
}
代码从流中读取,直到in遇到某个字符(由字节值表示),此时方法返回的任务完成

DoSomethingAsync
的函数签名是
unit->Async
,但我希望它是
unit->Task
,这样就可以在.NET中更普遍地使用它


这可以在F#中使用异步表达式来完成吗?或者我可以更依赖.NET的
任务
结构吗?

鉴于您的示例中没有实际使用异步工作流,最简单的解决方案是完全放弃它:

member x.DoSomethingAsync() =
    let tcs = new TaskCompletionSource<int>()
    Task.Delay(100).Wait()
    tcs.SetResult(10)
    tcs.Task
此实现还具有类型
unit->Task


根据更新的问题,这里有一种方法:

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
。我不知道在
的情况下要做什么,所以我只是把
-1
,但我相信你可以用更正确的东西来代替它。

考虑到你的示例中没有实际使用异步工作流,最简单的解决方案是完全放弃它:

member x.DoSomethingAsync() =
    let tcs = new TaskCompletionSource<int>()
    Task.Delay(100).Wait()
    tcs.SetResult(10)
    tcs.Task
此实现还具有类型
unit->Task


根据更新的问题,这里有一种方法:

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
。我不知道在
else
的情况下该怎么办,所以我只放了
-1
,但我相信您可以用更正确的东西来替换它。

给定的代码没有编译…添加了类以使其编译。它仍然没有编译。。。罪魁祸首是
Async.AwaitTask
,它没有将
Task
作为参数。Hmm。真奇怪。它在这里编译。另请参见给定的代码未编译…添加类使其编译。它仍然未编译。。。罪魁祸首是
Async.AwaitTask
,它没有将
Task
作为参数。Hmm。真奇怪。它在这里编译。另请参见假设我们返回的不是
Task.Delay
,而是
SetResult
所需的内容(示例中使用Delay是为了简洁)。难道我们不需要使用
let等待结果吗因此需要计算表达式?可能示例构造得不好。我试图更新它,希望它能更清楚地表达我的意图。@ploeh如果
缓冲区
还没有包含分隔符,那么函数应该再次调用自己来读取更多的流,而不是用-1来完成任务。当分隔符最终到达流中时,任务最终可以完成。这就是我试图用TaskCompletionSource建模的行为。我能理解
startask
使这更容易,因为我认为
else
块可以再次调用
DoSomethingAsync
。@lejon听起来很合理,尽管您可能需要一个递归函数来实现这一点。@p谢谢您的输入和回答。假设我们返回的不是
Task.Delay
,而是
SetResult
所需的内容(示例中使用Delay是为了简洁)。难道我们不需要使用
let等待结果吗因此需要计算表达式?可能示例构造得不好。我试图更新它,希望它能更清楚地表达我的意图。@ploeh如果
缓冲区
还没有包含分隔符,那么函数应该再次调用自己来读取更多的流,而不是用-1来完成任务。当分隔符最终到达流中时,任务最终可以完成。这就是我试图用TaskCompletionSource建模的行为。我很欣赏
startask
使这更容易,因为我认为
else
块可以再次调用
DoSomethingAsync
。@lejon听起来很合理,不过您可能需要一个递归函数来实现它。@ploeh感谢您的输入和回答。