繁体   English   中英

用F#实现C#异步接口

[英]Implement C# Async Interface with F#

我必须用F#实现一个C#接口。 我必须使用的接口和许多方法都是用C#编写的,并且非常重视异步。

从C#移植到F#的示例代码:

public async Task CloseAsync(PartitionContext context, CloseReason reason)
{
    Console.WriteLine(string.Format("Processor Shuting Down.  Partition '{0}', Reason: '{1}'.", this.partitionContext.Lease.PartitionId, reason.ToString()));
    if (reason == CloseReason.Shutdown)
    {
        await context.CheckpointAsync();
    }
}

这可能会有问题,因为F#和C#不使用相同的异步模式。 上面的函数是我需要实现的接口的一部分。 我的问题在于如何使用F#等待context.CheckpointAsync() ,使其仍然返回一个Task

这是我试图去的方向,但它不起作用。 context.CheckpointAsync返回Task<a>而不是Task 另外,其他情况如何,预计不会进行任何操作?

interface IEventProcessor with
    member this.CloseAsync(context:PartitionContext, reason:CloseReason) =
        match reason with
        | CloseReason.Shutdown -> context.CheckpointAsync() |> Async.AwaitTask
        | _ -> ()

任务也是IAsyncResult,这意味着您可以使用Async.AwaitIAsyncResult并忽略输出。

将它全部包装在异步计算表达式中,将其作为Task <unit>启动,然后转换为Task。

interface IEventProcessor with

    member __.CloseAsync(context : PartitionContext, reason : CloseReason) = 
        async { 
            if reason = CloseReason.Shutdown then 
                do! context.CheckpointAsync() |> Async.AwaitIAsyncResult |> Async.Ignore
        }
        |> Async.StartAsTask :> Task

问题是在C#中它的返回类型是Task而不是Task<T> 在完美的世界中,C#可以拥有Task<void>

F#3.x内置了从Task<T>Async<T>但不是从pla TaskAsync<T>绑定。 在SO上有样本,例如How to Async.AwaitTask on plain Task(not Task <T>)?

无论如何,看到你得到的确切错误会很有帮助但是看起来你的错误就是你正在尝试Async.AwaitTask (它将返回Async<T> )但接口必须是Task 所以你可以完全摆脱Async.AwaitTask()

然后你将得到另一个错误,匹配案例不会占用,即Shutdown分支返回Task ,而另一个分支返回unit 您需要更改它以返回Task

您可以避免使用异步并直接从CheckpointAsync返回任务:

match reason with
| CloseReason.Shutdown -> context.CheckpointAsync() :> Task
| _ -> Task.CompletedTask

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM