.net - 系统.IO.IOException : 'The process cannot access the file'

标签 .net multithreading f# 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)
    )

System.IO.IOException HResult=0x80070020 Message=The process cannot access the file 'log.txt' because it is being used by another process. Source=mscorlib

我错过了什么?

最佳答案

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

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

type private logginglock() =
    static let _lock = new obj()
    static member public lock = _lock

就是说,如果您只是将锁定对象作为模块中的全局值(只要它是模块私有(private)的),它也会同样有效。这可能会编译成与上面的代码非常相似的东西——尽管围绕锁定对象和单例有各种我从未完全理解的微妙之处……

let private loggingLock = obj()

关于.net - 系统.IO.IOException : 'The process cannot access the file' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53217527/

相关文章:

f# - 如何在 f# 中创建值为 "generic"的字典

F#使用GetEnumerator时无法枚举yield生成的序列

C# 每分钟 55 秒处调用方法

.net - 'custom environment' 中的 Razor 不接受 @model 指令

.net - XML - 根级别的数据无效

java - Intel i7 vs i5 使用 java 多线程

c# - 尝试引用 LINQ 命名空间时出现异常

iphone - 从辅助线程启动NSTimer时出现问题

c# - 如何在具有 2 个参数的函数上使用 System.Threading.Tasks.Task 进行异步调用?在.Net

.net - 什么是 Scala 的 Seq.Span 在 F# 中的等价物?