从C使用F#异步#

从C使用F#异步#,f#,async-await,F#,Async Await,假设我有以下代码: 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.ManagedT

假设我有以下代码:

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.startask像这样定义
X
如何

member this.X() = 
    let t = new Task(fun () -> bar |> Async.StartImmediate)
    t.RunSynchronously()
    t
据我所知,这是你想要的。至少,这个C代码:

打印此输出:

X 7
first bar 7
first async 7
last async 11

在这里,从C#中可以看到,
X
具有签名
Task X()

这完全符合我的要求(与此版本返回的问题不同,它也返回一个整数,即加号):

type public Class1()=
让printThread(消息)=printfn“%s%A”消息Thread.CurrentThread.ManagedThreadId
let bar=
打印线程(“第一条”)
异步{
printThread(“第一个异步”)
do!Async.Sleep(1000)
printThread“上次异步”
返回1232
}
成员:此。convertToTask)=

让tcs1=new taskCompletionSource正如我所说的,这不会满足我的问题,导致非异步代码在不同的线程中运行。所有线程Id都必须为7。实际上,我找到了我将在下面发布的答案。如果我运行这个,我会得到如下输出:
x8,第一个条8,第一个异步8,最后一个异步11
,就像我的(更简单的)答案一样。哦,是的,很抱歉,您可能在挂起主线程时从控制台应用程序尝试它。我从UI线程运行代码,所有打印语句返回相同的ID。您的代码在同步调用RunSynchronous时出现问题。它要么创建死锁,要么在另一个线程中运行最后一条语句+1如果我正确阅读了这个问题,这就是我要写的!
Console.WriteLine("X " + Thread.CurrentThread.ManagedThreadId);
var c = new Class1();            
c.X().Wait();

Thread.Sleep(2000);
X 7
first bar 7
first async 7
last async 11
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"
            return 1232
         }

    member this.convertToTask<'T> (asyn : Async<'T>) = 
       let tcs1 = new TaskCompletionSource<'T>()
       let t1 = tcs1.Task
       Async.StartWithContinuations
        (
          asyn 
          , (fun (k) -> tcs1.SetResult(k)), (fun exn -> tcs1.SetException(exn)), fun exn -> ())
        t1

    member this.X() : Task<int> =  (bar |> this.convertToTask)