The "finally" block in an async workflow will not normally run on the same thread as the code before the "try".

Both Mutex and ReaderWriterLock have OS thread affinity (they must use thread local store underneath), Using a Semaphore works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 

let log_file_lock = new Semaphore(1,1)

let logger  =
  MailboxProcessor.Start(fun inbox ->
    let rec loop() =
      async 
        { let! (path, entry) = inbox.Receive()
          let level = any_to_string entry.level 
          let msg = "[" + entry.timestamp.ToString() + "]\t" +"[" + level + "]\t" + entry.message 
          do printfn "acquiring..."
          let! _ = log_file_lock.WaitOneAsync(Timeout.Infinite) 
          do printfn "acquired..."
          try 
            if not (File.Exists(path)) then 
                use stream = File.Create(path) 
                do ()
            use stream = File.AppendText(path)
            do stream.WriteLine(msg) 
          finally
            try log_file_lock.Release() |> ignore 
            with e -> printfn "fail!, e = %A" e
          
          return! loop()             
        }
    loop()
  )

let log_extended path timestamp level msg = logger.Post((path, Entry.make timestamp level msg))

let log path level msg = log_extended path System.DateTime.Now level msg

By on 12/2/2007 7:26 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper