private const string RETRY_MAX_TIME_EXCEEDED = "The file \"{0}\" could not
be processed because a timeout occurred while waiting for the file to finish
uploading.";
private const int RETRY_MAX_TIME = 3600000; // 1 hour
private const int RETRY_DELAY = 10000; // 10 seconds
/// <summary>
/// The event handler that is called when a new file has been uploaded to
the
/// watched directory.
/// </summary>
private void FileCreated(object sender, FileSystemEventArgs args)
{
string filename = args.FullPath;
DateTime receivedAt = DateTime.Now;
bool timedOut = false;
bool processed = false;
//
// The event will be raised as soon as the first byte is written to the
file.
// Check to see if the file has completed uploading. If it hasn't, wait
for a
// specified delay and check again.
//
while (!(timedOut || processed))
{
if (FileUploadCompleted(filename))
{
ProcessFile(filename);
processed = true;
}
else
{
TimeSpan timeElapsed = DateTime.Now - receivedAt;
if (timeElapsed.TotalMilliseconds > RETRY_MAX_TIME)
{
timedOut = true;
}
else
{
Thread.Sleep(RETRY_DELAY);
}
}
}
if (timedOut)
{
LogError(String.Format(RETRY_MAX_TIME_EXCEEDED, filename));
}
}
/// <summary>
/// Returns true if the specified file has completed uploading and is ready
for
/// processing.
/// </summary>
private bool FileUploadCompleted(string filename)
{
//
// If the file can be opened for exclusive access it means that the file
// is no longer locked by the FTP server program and has completed
uploading.
//
try
{
using (FileStream inputStream = File.Open(filename, FileMode.Open,
FileAccess.Read,
FileShare.None))
{
return true;
}
}
catch (IOException)
{
return false;
}
}