Reputation: 383
I have a multi thread application. My problem is that sometimes I get an error like the program cannot access to a file as it is been used by something else (other part of the application).
Right now what I did is catch the exception and repeat the task after a 100ms delay.
It is working as the application does not open the files so often and it is open the files just for a short period.
Though I am not happy with that solution as it is ugly, and it still can go wrong.
Are there any good ways to sort out that problem? If there are not any easy answer and you need more information about the application(what files, why I might access in the same time) I can answer, I just try to keep the question simple, and generic.
Regards Daniel
EDIT:
I made up something fast, what do you guys think about that solution, it is not the most generic one, but had no better idea just now:
When the program try to write into the file check if the it is used or not. If it is used collect a data in the memory, as soon as the application want to write in to the file again and the file is free insert in all of the data.
It still not the best, but it might give some more ideas.
Upvotes: 0
Views: 346
Reputation: 86818
Since your application is both reading and writing the file, all you need to do is keep track of which files your application is using. Keep a dictionary of R/W locks keyed by file name. When you go to access a file, take out the appropriate lock.
Here's how you might code it:
Dictionary<string, ReaderWriterLockSlim> lockDict = new Dictionary<string, ReaderWriterLockSlim>();
ReaderWriterLockSlim LockFile(string filename, bool readOnly)
{
var fullPath = System.IO.Path.GetFullPath(filename);
ReaderWriterLockSlim myLock;
// lock the dictionary while we're accessing it
lock (lockDict)
{
if (!lockDict.TryGetValue(fullPath, out myLock))
{
myLock = new ReaderWriterLockSlim();
lockDict[fullPath] = myLock;
}
}
// only block on the file lock once the dictionary is unlocked
if (readOnly)
myLock.EnterReadLock();
else
myLock.EnterWriteLock();
// file is now "locked", so caller can proceed with read/write, then unlock
return myLock;
}
And you might use it like this:
// block until we're not using the file anymore
var myLock = LockFile(filename, readOnly: false);
try
{
using (var file = new StreamWriter(filename))
{
...
}
}
finally
{
myLock.ExitWriteLock();
}
Upvotes: 3