2

My case is I have the following method that uses SyncLock to ensure the writing of file by one thread at a time.

Private Shared lockThis As New Object 

Public Sub Process()
  SyncLock lockThis
    File.AppendAllText("c:\jamo\foo.txt","foo")
  End SyncLock 
End Sub 

I'm using many threads running at time:

Public Sub CreateThreads()
  Dim trd as Thread
  Dim X as Integer = 10
  For i as integer = 1 to X
    trd = New Thread(AddressOf Process)
    trd.Start()
  Next Sub
End Sub

My problem is when X is big (like 500), one o more threads write to file at same time. Why is happening this?

Jamo
  • 494
  • 5
  • 24
  • 2
    [Here is the C# version](http://stackoverflow.com/questions/4809843) of your question; the code appears to be equivalent to yours. One of the answers there suggests using the threadsafe `TextWriterTraceListener` class instead, which has it's own built-in locking mechanism. Trace listeners are the way to go if you need a decent, simple logging facility. – Robert Harvey Oct 22 '12 at 03:37
  • 1
    The answer Robert Harvey points to is a good suggestion, but are you accusing either `SyncLock` failing (by getting a "can't open for write exception") or that the data being logged by one thread is intermingled with data logged by another thread? (I hope it is the latter, and then it is probably "just" due to write-buffering somewhere.) – Mark Hurd Oct 22 '12 at 07:21
  • I can replicate the problem, writing 4522 characters instead of `"foo"` with `X` 2000 to my `C:\TEMP` in .NET 4 inside LINQPad. It is an IOException: "The process cannot access the file 'c:\temp\foo.txt' because it is being used by another process." from `System.IO.FileStream.Init`. So even though the code in `File.InternalAppendAllText` is using `Using`, the code is not closing the Win32 File completely before returning. – Mark Hurd Oct 22 '12 at 09:22
  • I want to add I have Threading.Thread.Sleep(seconds * 1000) in Process() next to SyncLock block. When it is in throws IOException using X = 500. Without Sleep this works. What is the problem? – Jamo Oct 22 '12 at 15:28
  • I also couldn't get it to occur when I switched to a true `vbc` compile, but I assume that's just because there's less going on with a true simple exe, compared to what LINQPad produces. I haven't looked into it further yet. I assume your `Sleep` is _outside_ the `SyncLock` block. – Mark Hurd Oct 24 '12 at 10:20
  • It didn't reoccur for me with the `Sleep` outside the `SyncLock` and, sorry Microsoft, but I allowed a simple `OutOfMemoryException` to upload to WER assuming it was an example of the failure when `Sleep` was inside the `SyncLock`. – Mark Hurd Oct 25 '12 at 01:48

1 Answers1

0

I don't have proof, but it could be telling the truth. If any other process opens the file without sharing it, with 500 or more threads attempting to open it, it is likely the file will be locked for one of them...

Mark Hurd
  • 10,665
  • 10
  • 68
  • 101