So, quickly looking through some of these and other similar questions, I went on a fun goose chase this afternoon, trying to solve the problem with two separate programs, using the file as a synchronization method (as well as saving the file). A bit unusual situation, but it definitely highlighted for me problems with "checking if the file is locked, and then open it if it doesn't fit."
The problem is this: the file may become locked between the time it was checked and the time you actually open the file. It is really difficult to track sporadic. It is impossible to copy a file because it is used by another process if you are not looking for it either.
The main permission is simply to try to open the file inside the catch block, so if you lock it, you can try again. Thus, there is no time between verification and opening; the operating system does this at the same time.
This code uses File.Copy, but it works just as well with any of the static methods of the File class: File.Open, File.ReadAllText, File.WriteAllText, etc.
Another small note about parallelism: This is a synchronous method that will block the stream both while waiting and when working on the stream. This is the easiest approach, but if the file remains locked for a long time, your program may stop responding. Parellelism is just too much for in-depth study here (and the number of ways you could configure it with asynchronous read / write is ridiculous), but here is one way that it can be parellelized.
public class FileEx { public static async void CopyWaitAsync(string src, string dst, int timeout, Action doWhenDone) { while (timeout > 0) { try { File.Copy(src, dst); doWhenDone(); break; } catch (IOException) { } await Task.Delay(100); timeout -= 100; } } public static async Task<string> ReadAllTextWaitAsync(string filePath, int timeout) { while (timeout > 0) { try { return File.ReadAllText(filePath); } catch (IOException) { } await Task.Delay(100); timeout -= 100; } return ""; } public static async void WriteAllTextWaitAsync(string filePath, string contents, int timeout) { while (timeout > 0) { try { File.WriteAllText(filePath, contents); return; } catch (IOException) { } await Task.Delay(100); timeout -= 100; } } }
And here is how to use it:
public static void Main() { test_FileEx(); Console.WriteLine("Me First!"); } public static async void test_FileEx() { await Task.Delay(1);