Can I use FileStream to implement a file lock?
Can I use the FileStream
constructor to ensure onl开发者_开发问答y one process accesses a file at a time? Will the following code work?
public static IDisposable AcquireFileLock() {
IDisposable lockObj;
do {
// spinlock - continually try to open the file until we succeed
lockObj = TryOpenLockFile();
// sleep for a little bit to let someone else have a go if we fail
if (lockObj == null) Thread.Sleep(100);
}
while (lockObj == null);
return lockObj;
}
private static FileStream TryOpenLockFile() {
try {
return new FileStream(s_LockFileName, FileMode.Create, FileAccess.Read, FileShare.None);
}
catch (IOException) {
return null;
}
}
In particular, is the behaviour with FileMode.Create
atomic WRT other processes? Is there something else I should be using?
EDIT: to be more specific, this is on the Microsoft CLR using local files on a single machine.
This will do what you want. FileShare.None
is the important part.
If all the writer apps are on the same computer, you could also use a named Mutex to achieve the same goal without a physical file being needed, or to mediate file access if you don't care who writes to the file last (just that writes are not concurrent). This could save you from having to reopen the file every time, and provide a blocking semantic instead of your Sleep
loop (better perf).
Note that any process can squat on your file (Mutex) if the name is not treated as a secret, i.e. information that needs to be kept secure.
This will work, given the following caveats:
- You are on Windows (on Linux via Mono, this doesn't hold up since file locks are advisory, so your method always succeeds)
- You are accessing a local file (SMB will also probably work, but NFS or WebDAV almost certainly won't)
- Catching IOException is probably too broad, you need to specifically verify that it failed because of a sharing violation
精彩评论