views:

1038

answers:

5

BACKGROUND: I use an offset into a file and the Filestream lock/unlock menthods to control read/write access. I am using the following code to test if a lock is currently held on the file

try
{
  fs.Lock( RESERVED_BYTE, 1 );
  fs.Unlock( RESERVED_BYTE, 1 );
  rc = 1;
}
catch
{ 
  rc = 0; 
}

QUESTION:
My goal is to eliminate the try/catch block. Is there some better way to see if the lock exists?

EDIT:
Note: This question is not about if the file exists. I already know it does. It is about synchronizing write access.

+5  A: 

Personally I would just catch a locked file when trying to open it. If it's unlocked now, it may be locked when you try to open it (even if it's just a few ms later).

Jon B
It's not about the open; I always open in read/write mode, but want to synchronize writing to some critical data structures.
Noah
A: 

I don't think it's possible without try, catch.

Koistya Navin
+4  A: 

You can call the LockFile API function through the P/Invoke layer directly. You would use the handle returned by the SafeFileHandle property on the FileStream.

Calling the API directly will allow you to check the return value for an error condition as opposed to resorting to catching an exception.


Noah asks if there is any overhead in making the call to the P/Invoke layer vs a try/catch.

The Lock file makes the same call through the P/Invoke layer and throws the exception if the call to LockFile returns 0. In your case, you aren't throwing an exception. In the event the file is locked, you will take less time because you aren't dealing with a stack unwind.

The actual P/Invoke setup is around seven instructions I believe (for comparison, COM interop is about 40), but that point is moot, since your call to LockFile is doing the same thing that the managed method does (use the P/Invoke layer).

casperOne
I had considered using the P/Invoke layer, but was concerned about the overhead vs using the try/catch. Any comments on that?
Noah
@Noah: See updated response.
casperOne
+4  A: 

My goal is to eliminate the try/catch block

Remember, the file system is volatile: just because your file is in one state for one operation doesn't mean it will be in the same state for the next operation. You have to be able to handle exceptions from the file system.

Joel Coehoorn
+1  A: 

In some circumstances you can also use WCT, it's usually implmented by debugger's or profilers, however it can be used from any code as the usual debugger requirement of being the thread which has the debug port open is not a pre-requisit. As such WCT is a very comprehensive and precise information regarding lock contention.

A managed example (all-be-it somewhat trickey), show's utility for this specific sub-set of the native debug API's on the CLR.

RandomNickName42
Just came across a really good MSDN zine on the topic,http://msdn.microsoft.com/en-ca/magazine/cc163618.aspx specific for .net, I thought it would be handy for some. The article is by Joe Duffy, I believe he's one of the primary parallel task lib dev's. I found it linked off of http://msdn.microsoft.com/en-us/magazine/cc546569.aspx which is a more general paper on locking issues, but it has a side-bar near the end, which has several references to more niche and involved topics on locking/core-wise development.
RandomNickName42