System.IO.IOException:'进程无法访问文件'

Sam*_*l J 2 .net f# multithreading locking

我正在尝试将日志记录同步到F Sharp项目中的文件.使用锁计算表达式我试图近似资源锁,但它似乎不起作用.

module regiondeployer.logger

open System
open System.IO
open Microsoft.FSharp.Core
open regiondeployer.personalprojectroot

type private logginglock =
    static member public lock = new Object()

[<Literal>]
let private logfile = personalprojectroot + "log.txt" 

let public initialize() : unit = 
    use init = File.Create(logfile)
    ()

let public logtoconsoleandfile (message:string) : unit =
    lock logginglock.lock (fun _ -> 
        Console.WriteLine message
        use logfilestream = File.AppendText(logfile)
        logfilestream.WriteLine(message)
    )
Run Code Online (Sandbox Code Playgroud)

System.IO.IOException HResult = 0x80070020 Message =进程无法访问文件'log.txt',因为它正被另一个进程使用.来源= mscorlib程序

我错过了什么?

Tom*_*cek 7

问题是你logginglock.lock是一个带有getter的属性,因此每次访问它时都会返回一个新对象.因此,线程将最终锁定不同的对象并实际同时访问该文件.

如果您坚持将锁定对象作为静态对象的字段,那么您可以使用定义静态字段static let,然后只返回该对象:

type private logginglock() =
    static let _lock = new obj()
    static member public lock = _lock
Run Code Online (Sandbox Code Playgroud)

也就是说,如果您将锁定对象作为模块中的全局值(只要它是模块专用),它就会同样有效.这可能会编译成与上面的代码非常相似的东西 - 尽管锁定对象和单例之间存在各种各样的细微之处,我从来都不太了解...

let private loggingLock = obj()
Run Code Online (Sandbox Code Playgroud)