C# 如何从C调用和处理异步F#工作流#
我读过一些F#教程,我注意到在F#中执行异步和并行编程比在C#中容易得多。因此,我试图编写一个F库,它将从C调用,并将C函数(委托)作为参数,异步运行 到目前为止,我已经成功地传递了这个函数(我甚至可以取消),但我错过的是如何实现回C#的回调,该回调将在异步操作完成后立即执行。(例如,函数AsynchronousTaskCompleted?)。此外,我还想知道是否可以将(例如进度%)发回F#from then function AsynchronousTask 有人能帮我吗 这是我到目前为止写的代码(我不熟悉F#,所以下面的代码可能是错误的或实现得很差) 要获得F#异步工作流的好处,您必须实际使用F#编写异步计算。您试图编写的代码将无法工作(即,它可能会运行,但不会有用) 在F#中编写异步计算时,可以使用C# 如何从C调用和处理异步F#工作流#,c#,asynchronous,f#,callback,workflow,C#,Asynchronous,F#,Callback,Workflow,我读过一些F#教程,我注意到在F#中执行异步和并行编程比在C#中容易得多。因此,我试图编写一个F库,它将从C调用,并将C函数(委托)作为参数,异步运行 到目前为止,我已经成功地传递了这个函数(我甚至可以取消),但我错过的是如何实现回C#的回调,该回调将在异步操作完成后立即执行。(例如,函数AsynchronousTaskCompleted?)。此外,我还想知道是否可以将(例如进度%)发回F#from then function AsynchronousTask 有人能帮我吗 这是我到目前为止写的
let代码>和执行代码>。这允许您使用其他基本的非阻塞计算。例如,您可以使用Async.Sleep
而不是Thread.Sleep
// This is a synchronous call that will block thread for 1 sec
async { do Thread.Sleep(1000)
someMoreStuff() }
// This is an asynchronous call that will not block threads - it will create
// a timer and when the timer elapses, it will call 'someMoreStuff'
async { do! Async.Sleep(1000)
someMoreStuff() }
只能在async
块中使用异步操作,这取决于F#compiler处理的方式代码>和让我们来代码>。对于以顺序方式编写的代码(例如,在C#中或在async
block in F#之外),没有(简单的)方法可以获得真正的非阻塞执行
如果您想使用F#获得异步工作流的好处,那么最好的选择是在F#中实现操作,然后使用Async.startask
(这使您可以轻松使用任务
)。大概是这样的:
let someFunction(n) = async {
do! Async.Sleep(n)
Console.WriteLine("working")
do! Async.Sleep(n)
Console.WriteLine("done")
return 10 }
type AsyncStuff() =
member x.Foo(n) = someFunction(n) |> Async.StartAsTask
// In C#, you can write:
var as = new AsyncStuff()
as.Foo(1000).ContinueWith(op =>
// 'Value' will throw if there was an exception
Console.WriteLine(op.Value))
如果您不想使用F#(至少在实现异步计算时是这样),那么异步工作流对您没有帮助。您可以使用任务
、BackgroundWorker
或其他C#技术实现类似的功能(但您将失去在不阻塞线程的情况下轻松运行操作的能力)。代码似乎工作正常,但我不确定它是否应该以这种方式实现。如果我用F#写异步计算,我能从C#使用它吗?谢谢你的回答,我会尝试熟悉异步计算。@loannis:我添加了一些信息和示例,说明如何用F#写异步工作流,并使用startask
从C#使用它。希望这会有帮助!非常感谢你对我的帮助。谢谢你的提问和回答@Tomas,你知道有没有办法在C中使用F的异步类型,或者你通常会建议让你的F代码C友好,而不是相反?
let someFunction(n) = async {
do! Async.Sleep(n)
Console.WriteLine("working")
do! Async.Sleep(n)
Console.WriteLine("done")
return 10 }
type AsyncStuff() =
member x.Foo(n) = someFunction(n) |> Async.StartAsTask
// In C#, you can write:
var as = new AsyncStuff()
as.Foo(1000).ContinueWith(op =>
// 'Value' will throw if there was an exception
Console.WriteLine(op.Value))