Async из Async.AwaitEvent и многопоточность - PullRequest
0 голосов
/ 01 апреля 2012

Это упрощенная версия проблемы, с которой я имею дело.У него есть резьбовая петля, которую я не могу контролировать.Время обработки сообщения - больше, чем время для цикла.

Я не могу ничего переписать в mytype рядом с отмеченным разделом в StartAsync.

Не могли бы вы мне помочь?инструкции, которые могут справиться с такими условиями?Например, есть ли версия syncContext.Post с очередью?Любая помощь приветствуется

type mytype () = 
  let FinishedEvt    = new Event<_>()
  let FirstEvt       = new Event<_>()
  member x.First       = FirstEvt.Publish
  member x.Finished    = FinishedEvt.Publish

  member x.StartAsync() = 

     async {
     let syncContext =  match System.Threading.SynchronizationContext.Current with
                        | null -> new System.Threading.SynchronizationContext()
                        | other -> other 
     do! Async.SwitchToNewThread()
     //**the code that I can change is here**
     Thread.Sleep(100)
     syncContext.Post(SendOrPostCallback(fun _ -> FirstEvt.Trigger    ()), null)
     Thread.Sleep(200)
     syncContext.Post(SendOrPostCallback(fun _ -> FinishedEvt.Trigger ()), null)
     do! Async.SwitchToContext(syncContext) 
     ()
  }
     let hopingobject = mytype()
     let wf1 = lock readLock1 
                    (fun () -> 
                               async{ printfn "watching"
                                      do! Async.AwaitEvent hopingobject.First
                                      printfn "first event received"
                                      do! Async.AwaitEvent hopingobject.Finished
                                      printfn "I never get called"} )

     hopingobject.StartAsync() |> Async.Start
     wf1 |> Async.RunSynchronously
     printfn "the end"
     Console.ReadKey() |> ignore

1 Ответ

3 голосов
/ 01 апреля 2012

Мне неясно, что вы пытаетесь сделать, и какие части важны, но этот бит

async{ printfn "watching" 
       do! Async.AwaitEvent hopingobject.First 
       printfn "first event received" 
       do! Async.AwaitEvent hopingobject.Finished 
       printfn "I never get called"}

выглядит неправильно для меня, так как вы не начинаете слушать Finished до тех пор, пока не обработаетеВо-первых, в этот момент «Готово» уже может быть запущено.Возможно, вы хотите что-то более похожее на

async{ printfn "watching" 
       let! a = Async.AwaitEvent hopingobject.First |> Async.StartChild
       let! b = Async.AwaitEvent hopingobject.Finished |> Async.StartChild
       do! a
       printfn "first event received" 
       do! b
       printfn "hurray, I never called"}

(я пишу код в браузере, надеюсь, что это правильно.) Идея состоит в том, чтобы начать слушать оба в начале, но затем ждать сначала, а затемжди Готово.

...