F# 线程中的取消标记

Posted

技术标签:

【中文标题】F# 线程中的取消标记【英文标题】:cancellation token in F# threads 【发布时间】:2021-04-14 16:26:15 【问题描述】:

我正在努力解决以下问题:

我有一个系统,它有它的主要流程,并且有两个可以启动和停止的后台线程,但它们通常运行时间很长,因为它们只在配置更改期间停止。

我发现 F# 中的取消标记在代码中的异步点被检查。 工作线程不执行任何异步操作;他们正在做后台工作,但没有什么是异步的。

简化版如下所示:

let workerThread (someParameters) =
    async 
        while true do
            setup some event driven system that has a callback when work is finished
            on callback, signal
            waitHandle.WaitOne()                

它是这样开始的:

Async.StartAsTask(workerThread parameter, cancellationToken = cancellationSource.Token)

由于系统中绝对没有异步,因此永远不会检查取消令牌,此外,我需要能够在两个工作线程不断设置的事件驱动系统中手动检查它。

如何做到这一点?在 C# 中,令牌是直接传递的,我可以随时检查它。

【问题讨论】:

你不能将令牌作为参数传递给workerThread吗? 是的,我可以,但我认为,也许是错误的,有一种机制可以访问它,因为它必须被带到线程中 【参考方案1】:

F# 将取消令牌传播到创建的任务,但如果工作函数在等待句柄时被阻塞,则它无法检查取消令牌。要解决此问题,您还应该等待取消令牌等待句柄:

let workerThread () =
  async 
      let! token = Async.CancellationToken // this way you can get cancellation token
      while true do
          // whatever
          WaitHandle.WaitAny([| waitHandle; token.WaitHandle |]) |> ignore
  

【讨论】:

以上是关于F# 线程中的取消标记的主要内容,如果未能解决你的问题,请参考以下文章

如果我在 C++ 中的一个线程中分配内存,我可以在另一个线程中取消分配它吗

如何使“主线程”等待“子线程”执行结束后再继续执行

在 Windows 中的另一个线程上异步启动和取消 I/O 的无竞争方式

linux下pthread_cancel无法取消线程的原因

多线程下的任务取消

SylixOS 线程取消处理流程