gpt4 book ai didi

f# - 从 C# 使用 F# Async

转载 作者:行者123 更新时间:2023-12-04 15:22:44 25 4
gpt4 key购买 nike

假设我有以下代码:

namespace Library1

open System.Threading.Tasks
open System.Threading
open System.Runtime.Remoting.Messaging
open System

type public Class1() =

let printThread (message) =
printfn "%s %A" message Thread.CurrentThread.ManagedThreadId

let bar =
printThread ("first bar")
async {
printThread ("first async")
do! Async.Sleep(1000)
printThread "last async"
}

member this.X() = bar

我想使用这个类并从 C# 调用 X。问题是 X 返回一个 Async<'T>。但是,公开 F# 特定类型是不好的做法。所以最好的做法是返回一个任务。但是 Async.StartAsTask 有点问题,因为它会导致代码在单独的线程中运行。我想要的是我想返回一个任务,但它也应该表现为 Async.StartImmediate。因此代码的非异步部分应该在原始主线程中运行。 在这里,我假设我从 UI 线程 运行它这样所有调用都将返回相同的线程 ID。换句话说,我想要一个 Async.StartImmediate 但返回一个任务。
这是可以实现的吗?

最佳答案

您可以转Async<'T>进入 Task<'T>使用 Async.StartAsTask<'T>方法。

我通常建议让 C# 用户更容易,并使用返回 Task<'T> 的附加方法扩展 F# 实现。 .按照通常的命名约定,您可以调用 F# 版本 AsyncFoo和 C# 友好版本 FooAsync .

看看你的例子,我会用这样的东西:

type public Class1() =

let printThread (message) =
printfn "%s %A" message Thread.CurrentThread.ManagedThreadId

let bar =
printThread ("first bar")
async {
printThread ("first async")
do! Async.Sleep(1000)
printThread "last async"
}

member this.AsyncFoo() = bar

/// Expose C#-friendly asynchronous method that returns Task
member this.FooAsync() = Async.StartAsTask(bar)
/// Expose C#-friendly asynchronous method that returns Task
/// and takes cancellation token to support cancellation...
member this.FooAsync(cancellationToken) =
Async.StartAsTask(bar, ?cancellationToken=cancellationToken)

关于f# - 从 C# 使用 F# Async,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22784350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com