With this code for a very basic logger:
lock (string.Concat("LogWritter_", this.FileName))
{
using (var fileStream = File.Open(this.FileName, FileMode.Append, FileAccess.Write, FileShare.Read))
{
using (var w = new StreamWriter(fileStream))
{
w.Write(message);
}
}
}
when I try it from a few threads simultaneously I quickly get the error:
The process can't access the file because its being used by another file.
Why the lock is not preventing the threads to access the file at the same time?
It doesn't matter if the threads call the same instance or different instances to the same file. Also I thought It could be because of some deferral when writing files in Windows, but on Linux happens the same thing.
You are locking on a temporary string. You have to introduce a static object to lock on.
Create a Dictionary<string,object>
and store your lock objects there with the filepath as key.
A while back, I approached this same question:
Locking by string. Is this safe/sane?
The C# lock statement places a lock on the object, not the uniqueness of the string. So, because you are dynamically concatenated two strings, you are essentially creating a new object every single time, so every single lock is unique. Even if you access the same file every time, "A" + "B" results in some new immutable string; "A" + "B" again results in yet another new object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With