Коротка порада для всіх, хто приходить сюди зі схожою проблемою:
Слідкуйте за додатками для веб-синхронізації, такими як DropBox. Я щойно провів 2 години, думаючи, що "використовуючи" заяву (Dispose pattern) порушено в .NET.
Зрештою я зрозумів, що Dropbox постійно читає і записує файли у фоновому режимі, щоб синхронізувати їх.
Здогадайтесь, де знаходиться моя папка Visual Studio Projects? Всередині папки "Мій Dropbox" звичайно.
Тому, коли я запускав свою програму в режимі налагодження, DropBox також постійно отримував доступ до файлів, які вона читала і записувала, щоб синхронізуватися з сервером DropBox. Це спричинило конфлікти блокування / доступу.
Так що я, принаймні, тепер знаю, що мені потрібна більш міцна функція відкриття файлів (тобто TryOpen (), яка зробить кілька спроб). Я здивований, що це вже не вбудована частина фреймворку.
[Оновлення]
Ось моя функція помічника:
/// <summary>
/// Tries to open a file, with a user defined number of attempt and Sleep delay between attempts.
/// </summary>
/// <param name="filePath">The full file path to be opened</param>
/// <param name="fileMode">Required file mode enum value(see MSDN documentation)</param>
/// <param name="fileAccess">Required file access enum value(see MSDN documentation)</param>
/// <param name="fileShare">Required file share enum value(see MSDN documentation)</param>
/// <param name="maximumAttempts">The total number of attempts to make (multiply by attemptWaitMS for the maximum time the function with Try opening the file)</param>
/// <param name="attemptWaitMS">The delay in Milliseconds between each attempt.</param>
/// <returns>A valid FileStream object for the opened file, or null if the File could not be opened after the required attempts</returns>
public FileStream TryOpen(string filePath, FileMode fileMode, FileAccess fileAccess,FileShare fileShare,int maximumAttempts,int attemptWaitMS)
{
FileStream fs = null;
int attempts = 0;
// Loop allow multiple attempts
while (true)
{
try
{
fs = File.Open(filePath, fileMode, fileAccess, fileShare);
//If we get here, the File.Open succeeded, so break out of the loop and return the FileStream
break;
}
catch (IOException ioEx)
{
// IOExcception is thrown if the file is in use by another process.
// Check the numbere of attempts to ensure no infinite loop
attempts++;
if (attempts > maximumAttempts)
{
// Too many attempts,cannot Open File, break and return null
fs = null;
break;
}
else
{
// Sleep before making another attempt
Thread.Sleep(attemptWaitMS);
}
}
}
// Reutn the filestream, may be valid or null
return fs;
}