F#线程中的取消令牌 [英] cancellation token in F# threads

查看:62
本文介绍了F#线程中的取消令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

简化版本如下:

  let workerThread(someParameters)=异步{虽然是真的设置一些事件驱动的系统,该系统在工作完成时具有回调回调时,发出信号waitHandle.WaitOne()} 

它开始像这样:

  Async.StartAsTask(workerThread参数,cancelledToken = cancelSourceSource.Token) 

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

这怎么办?在C#中,令牌直接传递,我可以随时检查它.

解决方案

F#将取消令牌传播到所创建的任务,但是如果在等待句柄时阻止了工作程序功能,则它无法检查取消令牌.要解决此问题,您还应该等待取消令牌等待句柄:

  let workerThread()=异步{让!token = Async.CancellationToken//通过这种方式,您可以获得取消令牌虽然是真的//任何WaitHandle.WaitAny([| waitHandle; token.WaitHandle |])|>忽略} 

I am struggling with the following:

I have a system that has its main flow and has two background threads that can be started and stopped, but they're generally very long running as they stop only during configuration changes.

I found that the cancellation token in F# gets checked at async points in the code. The worker threads do not perform any async operations; they are doing background work but nothing is asynchronous.

A simplified version looks like that:

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()                
}

and it gets started like this:

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

Since there is absolutely nothing async in the system, the cancellation token will never be checked and, besides, I need to be able to manually check it in the event driven systems that keep getting set up by the two worker threads.

How can this be done? In C# the token is passed directly and I can check it whenever I feel like.

解决方案

F# propagates cancellation token to the task which is created, but if worker function is blocked while waiting for a handle it cannot check the cancellation token. To solve this issue you should wait for the cancellation token wait handle as well:

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#线程中的取消令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆