在F#中,我可以在一个线程上调用一个函数,但在另一个线程上返回吗?

时间:2009-01-26 16:42:47

标签: .net multithreading f#

我真的希望能够让一个函数将一些责任传递给另一个对象,然后返回另一个线程。我知道这意味着调用者不会知道它已经切换了线程,但我真的想知道是否有任何方法让函数返回不同于调用它的线程。

3 个答案:

答案 0 :(得分:3)

您似乎对线程如何工作有一些误解。 您不能在一个线程中输入函数并在另一个线程中退出(线程具有单独的堆栈,并且堆栈保持您所使用的功能)。 你可以做的是使用Asynchronous api,它调用一个立即返回的函数,并允许稍后重新生成结果。

选项包括:

返回一些值,它将允许查询异步操作的状态('你还没完成')并允许在结果指示完成后检索结果('给出结果')这些通常允许使用多线程。

为原始函数提供一个函数,该函数将在以后结果完成时调用(通常,发生此回调的线程没有很好地定义,因为它很可能来自某个线程池。

异步api通常很复杂。

通常需要的是对一个函数调用同步调用另一个线程上的其他函数。常见的例子是将一些调用走私到事件循环调度线程(在窗口中通过Invoke()方法)。

系统可能提供相当于fork()的线程,其中整个线程被克隆(包括到目前为止的堆栈),然后两个线程都从函数返回。这种行为很可能容易出错。

Continuations可以提供一种受控制的方式来完成你想要实现的目标,但它们非常复杂并且可能会损害你想要实现的目标的可读性。

答案 1 :(得分:2)

异步工作流程会产生类似这样的错觉,例如

async {
    printfn "on thread 1..."
    let! r = stream.ReadAsync()
    printfn "on thread 2 now..."
    ...
}

但让代码易于阅读,编写和推理只是一种幻想;在引擎盖下,它使用BeginRead / EndRead / callbacks / etc执行所有正常的异步操作。

答案 2 :(得分:0)

使用.NET异步委托,您可以将对象传递给在单独线程上执行的函数,并在完成后让它执行回调函数。该回调函数将在与主线程不同的线程上调用。

如果您熟悉C#或Visual Basic,可以在.NET中找到有关使用异步委托的大量信息。我没有在F#中看到对异步委托的良好处理。