为什么 Threading.Timer 不能在异步块中工作?

wang kai

这个程序工作正常:

let mutable inc =0

let a(o:obj)=
  let autoEvent=o :?> AutoResetEvent
  Console.WriteLine("a")
  inc<-inc+1
  if inc=3 then
     autoEvent.Set()|>ignore

let autoEvent=new AutoResetEvent(false)
let timer=new Timer(a,autoEvent,0,2000)
autoEvent.WaitOne()|>ignore    

但是当我想处理 tcp 客户端时,将相同的代码放在 async 块中时:

let mutable inc =0

let a(o:obj)=
  let autoEvent=o :?> AutoResetEvent
  Console.WriteLine("a")
  inc<-inc+1
  if inc=3 then
     autoEvent.Set()|>ignore

let listener=new TcpListener(IPAddress.Parse("127.0.0.1"),2000)

let private loop(client:TcpClient,sr:StreamReader,sw:StreamWriter)=
  async{
    let autoEvent=new AutoResetEvent(false)
    let timer=new Timer(a,autoEvent,0,2000)
    autoEvent.WaitOne()|>ignore
 }

let private startLoop()=
  while true do
    let client=listener.AcceptTcpClient()
    let stream=client.GetStream()
    let sr=new StreamReader(stream)
    let sw=new StreamWriter(stream)
    sw.AutoFlush<-true
    Async.Start(loop(client,sr,sw))|>ignore

listener.Start()
startLoop()
listener.Stop()    

定时器功能运行3次后不会退出。我想知道为什么?谢谢

奇弗罗

我首先想提几件事,而不是使用Console.WriteLine("a"),只需使用printfn "a"其次,您提供的代码片段不会终止,因此如果您在 FSI 中尝试,它会在主线程完成后继续运行。这在控制台应用程序中可能不是问题。要回答您的问题,它与异步工作流程有关。如果您喜欢这篇文章:Async Programming,您会注意到它们将异步计算作为子项生成,然后执行异步睡眠以让子项有机会开始。这与任务的调度方式有关。.NET Framework 使用“工作优先”策略。在阻塞事件迫使线程放弃当前任务之前,通常不会执行继续。这就是我让计时器事件运行的方式:

open System
open System.Threading

let mutable inc =0

let a(o:obj)=
  let autoEvent=o :?> AutoResetEvent
  printfn "a"
  inc<-inc+1
  if inc=3 then
    printfn "hit 3!"
    //autoEvent.Set()|>ignore

let private loop i =
  async{
    printfn "Started as child..."
    let aWrap(o:obj) = // so that we can see which child prints
      printfn "%d" i
    let autoEvent=new AutoResetEvent(false)
    let timer=new Timer(aWrap,autoEvent,0,2000)
    autoEvent.WaitOne()|>ignore
  }

let startLoopAsync() =
  async {
    let children =
      [1..3]
      |> List.map(fun i ->
        Async.StartChild(loop i) // start as child
      )
    do! Async.Sleep 100 // give chance for children to start
    children
    |> List.iter (Async.RunSynchronously >> ignore) // wait for all children
  }


startLoopAsync() |> (Async.RunSynchronously >> ignore) // wait for async loop start
Thread.Sleep(5000)

请注意,我使用了StartChild. 我推荐这个是因为这里提到的事实:Async.Start vs. Async.StartChild子异步任务不需要获得自己的取消令牌。相反,它从其父级继承。所以,如果我给 分配了一个取消标记startLoopAsync(),我就可以取消那个任务,所有的孩子也会取消。最后,我建议保持一个句柄timer,以防您需要停止再次发生的事件。不保留句柄将导致无法在不终止进程的情况下停止它。那是Thread.Sleep(5000)为了什么为了表明在异步任务完成后,计时器会不断触发事件,直到进程终止(如果您使用它进行测试,则需要终止 FSI)。

我希望这能回答你的问题,
干杯!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我不能在WPF中通过System.Threading.Timer调用使用CapturePhotoToStreamAsync?

来自分类Dev

System.Threading.Timer无法正常工作

来自分类Dev

System.Threading.Timer无法持续工作

来自分类Dev

为什么我不能在Timer.scheduledTimer函数中更改变量的值?

来自分类Dev

为什么不能在try / catch块中访问变量?

来自分类Dev

为什么我不能在异步方法中调试代码?

来自分类Dev

自动处理Threading.Timer

来自分类Dev

为什么margin不能在div中工作?

来自分类Dev

为什么我的模型不能在serviceRepository laravel中工作?

来自分类Dev

为什么我的硒不能在python脚本中工作?

来自分类Dev

为什么move方法不能在Java中工作?

来自分类Dev

为什么我的线性渐变不能在Firefox中工作?

来自分类Dev

为什么不能在angularJs ng模式中工作?

来自分类Dev

为什么异步函数返回System.Threading.Tasks.Task`1 [System.String]?

来自分类Dev

用自定义异步计时器类替换Threading.Timer?

来自分类Dev

为什么我的`main()`不能捕获junit测试中`timer`中抛出的异常?

来自分类Dev

为什么我的`main()`不能捕获junit测试中`timer`抛出的异常?

来自分类Dev

为什么threading.Thread通过阻止python 2.5中的执行来同步运行?

来自分类Dev

为什么bash(mono)中的gmcs命令缺少名称空间“ System.Threading”?

来自分类Dev

有没有办法扩展python中的threading.Timer

来自分类Dev

捕获上下文管理器中threading.Timer引发的异常

来自分类Dev

Windows服务任务中的C#Threading.Timer并非总是触发

来自分类Dev

Xamarin.Forms中的Device.StartTimer与System.Threading.Timer

来自分类Dev

Windows服务任务中的C#Threading.Timer并非总是触发

来自分类Dev

C#Winforms System.Threading.Timer

来自分类Dev

System.Threading.Timer低级实现

来自分类Dev

System.Threading.Timer停止线程?

来自分类Dev

Python的threading.timer / for循环问题

来自分类Dev

Threading.Timer时间间隔随机

Related 相关文章

  1. 1

    为什么我不能在WPF中通过System.Threading.Timer调用使用CapturePhotoToStreamAsync?

  2. 2

    System.Threading.Timer无法正常工作

  3. 3

    System.Threading.Timer无法持续工作

  4. 4

    为什么我不能在Timer.scheduledTimer函数中更改变量的值?

  5. 5

    为什么不能在try / catch块中访问变量?

  6. 6

    为什么我不能在异步方法中调试代码?

  7. 7

    自动处理Threading.Timer

  8. 8

    为什么margin不能在div中工作?

  9. 9

    为什么我的模型不能在serviceRepository laravel中工作?

  10. 10

    为什么我的硒不能在python脚本中工作?

  11. 11

    为什么move方法不能在Java中工作?

  12. 12

    为什么我的线性渐变不能在Firefox中工作?

  13. 13

    为什么不能在angularJs ng模式中工作?

  14. 14

    为什么异步函数返回System.Threading.Tasks.Task`1 [System.String]?

  15. 15

    用自定义异步计时器类替换Threading.Timer?

  16. 16

    为什么我的`main()`不能捕获junit测试中`timer`中抛出的异常?

  17. 17

    为什么我的`main()`不能捕获junit测试中`timer`抛出的异常?

  18. 18

    为什么threading.Thread通过阻止python 2.5中的执行来同步运行?

  19. 19

    为什么bash(mono)中的gmcs命令缺少名称空间“ System.Threading”?

  20. 20

    有没有办法扩展python中的threading.Timer

  21. 21

    捕获上下文管理器中threading.Timer引发的异常

  22. 22

    Windows服务任务中的C#Threading.Timer并非总是触发

  23. 23

    Xamarin.Forms中的Device.StartTimer与System.Threading.Timer

  24. 24

    Windows服务任务中的C#Threading.Timer并非总是触发

  25. 25

    C#Winforms System.Threading.Timer

  26. 26

    System.Threading.Timer低级实现

  27. 27

    System.Threading.Timer停止线程?

  28. 28

    Python的threading.timer / for循环问题

  29. 29

    Threading.Timer时间间隔随机

热门标签

归档