File.Move Delay Between Processes

G

Guest

Hi All!

I'm developing in C# using .NET 2003 Enterprise Developer (.NET Framework
1.1.4322 SP1) running on Windows 2000.

I'm attempting to "lock" a file that's used by two processes by adding a
".LOK" extension to the end of the filename. When I rename the file in a
local directory using the System.IO.File.Move method, there seems to be a
slight delay between the time the file is renamed and the time that other
processes recognize that the change occurred. For example, I have two
instances of the same application running on the same machine (Process A and
Process B). Both processes are working with the same local file
(c:\temp\TestLockFile\TestFile.txt). Process A checks to see whether
TestFile.txt exists (in other words has not been renamed by Process B) using
the File.Exists method. If the file exists (has not been renamed by Process
B), Process A attempts to rename TestFile.txt to TestFile.txt.LOK using the
File.Move method.

Meanwhile, Process B is performing the same logic described above for
Process A. Inevitably, this leads to situations where Process A and Process
B check to see whether TestFile.txt exists using the File.Exists method at
almost the same instant. As expected, since neither process has renamed the
file yet, each process sees that TestFile.txt exists (has not been renamed by
the other process). However, the issue that I'm running into is that neither
process is throwing an error in these situations. Instead, each process
proceeds as if it was the one that renamed TestFile.txt. It seems to me, for
example, that if Process A executes the File.Move method even a millisecond
before Process B does, the File.Move method should throw a
FileNotFoundException in Process B (since Process A already renamed
TestFile.txt to TestFile.txt.LOK). Am I missing something? Is there a way
to ensure that both processes can't rename TestFile.txt at the same time? Or
is there perhaps a different proven approach to "locking" a file that's used
by multiple processes?

I'm able to reproduce the scenario above (most of the time) by forcing both
processes to rename TestFile.txt at almost the same instant using the
following code. Notice that the logic makes each process wait until the
system clock reaches the next minute.

private void LockFile(string strOriginalPath)
{
try
{
string strNewPath = strOriginalPath + ".LOK";
string strMessage = "";

//see if the original file exists
if(File.Exists(strOriginalPath))
{
//get the datetime object for the next minute and wait for it to
elapse
System.DateTime dtNow = System.DateTime.Now;
int iYear = dtNow.Year;
int iMonth = dtNow.Month;
int iDay = dtNow.Day;
int iHour = dtNow.Hour;
int iMinute = dtNow.Minute + 1;
System.DateTime dtNextMinute = new System.DateTime(iYear,
iMonth, iDay, iHour, iMinute, 0);
while(dtNextMinute.CompareTo(System.DateTime.Now) > 0)
{
//wait until calculated time (ie. next even minute on system
clock)...
}

//attempt to rename the file
File.Move(strOriginalPath, strNewPath);

//verify it was renamed
if(!File.Exists(strNewPath))
{
strMessage += "Unable to lock file " + strOriginalPath + ".";
throw new ApplicationException(strMessage);
}
}
else
{
//see if the file was already renamed
if(File.Exists(strNewPath))
strMessage += strOriginalPath + " already locked.";
else
strMessage += strOriginalPath + " does not exist.";

throw new ApplicationException(strMessage);
}
}
catch
{
throw;
}
}


Thanks in advance for your advice, Dave
 
T

Trevor Braun

Could this be an issue with write caching?

As an answer to your second part, to lock a file, use:
File.Open(path2File, FileMode.Open, FileAccess.Read, FileShare.None);

This will ensure that no other process can touch the file until you're done
with it.

Trevor Braun
 
G

Guest

Thanks for your response Trevor. Using the File.Open method does seem to
prevent both processes from "locking" the file at the same time. However,
opening the file exclusively seems to have the side-effect of preventing the
process that opened the file from copying it to another location, which is
one of the next steps in my process.

Is there a way to force the File.Move to take effect immediately or another
way to "lock" a file immediately in such a way that the process with the
"lock" can manipulate the file any way it needs to?

-Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top