views:

133

answers:

2

Hi All,

I am using C# in an application and am having some problems with a file becoming locked.

The piece of code does this,

while (true)
{
   Read a packet from a socket (with data in it to add to the file)
   Open a file // one of these randomly throws an exception saying that the file is locked
   Writes data to it
   Close a file
} 

But in the process the file becomes locked. I don't really understand how, we are are definately catching and reporting exceptions so I don't see how the file doesn't get closed every time.

My best guess is that something else is opening the file. It is not likely to be another app, but it could be a different thread, but I just want to prove it either way. Can someone please provide a piece of code to check whether the file is open and if so report what processId and threadId has the file open.

For example if I had this code,

StreamWriter streamWriter1 = new StreamWriter(@"c:\logs\test.txt");
streamWriter1.WriteLine("Test");
// code to check for locks??
StreamWriter streamWriter2 = new StreamWriter(@"c:\logs\test.txt");
streamWriter1.Close();
streamWriter2.Close();

That will throw an exception because the file is locked when we try and open it the second time. So where the comment is what could I put in there to report that the current app (process Id) and the current thread (thread Id) have the file locked?

Thanks.

+2  A: 

This doesn't directly answer your question, but free Sysinternals tools like Process Explorer and Process Monitor are really useful for this kind of debugging.

Brian
Yeah but it is not going to work in this case because the file is opened and closed so many times, and it happens too quickly for me to see it with a tool like this. I have already tried
peter
At the point of exception (attached to a debugger), you should be able to switch to Proc Exp and search for the file name and see who is holding the handle. Am I missing something ?
Gishu
I am not able to debug. I am running this on a netbook that belongs to a client. The problem is specific to this netbook for some reason. I will keep trying, but the previous times I have searched for the handles in process explorer the list returned back was empty.
peter
I think it is because the file is continually opened and closed, so most of the time it will be the socket connection that is using up time so the file will be closed.
peter
I will try my luck again with process explorer
peter
+1  A: 

Here's some pseudocode that will protect the resource across threads:

while (true)
{
   Read a packet from a socket (with data in it to add to the file)
   lock (static locker object)
   {
       Open a file
       Writes data to it
       Close a file
    }
}

in the C# world, the static locker object is usually declared at the class level thusly:

private static readonly object locker = new object();

I would also recommend using the using keyword to protect the file resource if the statements between the opening and closing of the file throws an exception. Re-done pseudocode:

while (true)
{
   Read a packet from a socket (with data in it to add to the file)
   lock (static locker object)
   {
       using (Open a file)
       {
           Writes data to it
       } // leaving the using block will close the file
    }
}
Jesse C. Slicer
Thanks. It is currently using a 'using', although I didn't mention that above. But yeah, good point about the locking. I didn't initially think it was a threading issue, but in process monitor I see a lot of threads being created and destroyed. This is a complicated application so the threading could be something else totally, but I will check it out as it might do the trick.
peter
Having said that a lot of our clients don't have this file locking issue. I would have thought it would be more prominent if it was something like threading and locking. But of course I will try and see what happens. Great suggestion all the same.
peter
I was able to replicate the error you're receiving pretty easily in a test environment I set up which did not have the locking mechanism. I then added the locking mechanism and didn't get a file lock exception. This is definitely one of those bugs which will be environment-specific: processor speed, multicore, IO subsystem speed, etc. will play roles in determining if a thread tries to use that file while in use by another thread.
Jesse C. Slicer
Guess what ... there is more than meets the eye here. I found that if the file is locked I do a 'Thread.Sleep(500);' and then try again, and log the number of retries that occur. It seems that sometimes it just takes longer for the file to 'close'. After a couple of retries it works properly.
peter
I am running this on a netbook, and it looks like it just cannot keep up. After the first locking issue, a retry keeps it running, but after that it has to do the retries quite a lot. It seems like the OS and hardware increasingly gets behind in what it can handle.
peter
The solution I think is that the file should only be opened at the start, and closed at the end instead of all the time with each packet arriving. But I just had to go through these intermediate steps so that I can prove and understand what the problem is. I am in a situation where I cannot make assumptions as people will want answers.
peter