Vì vậy, sau khi liếc nhanh chóng thông qua một số những điều này và khác những câu hỏi tương tự như tôi đi vào một cuộc rượt đuổi ngỗng vui vẻ chiều nay cố gắng để giải quyết một vấn đề với hai chương trình riêng biệt sử dụng một tệp dưới dạng phương thức đồng bộ hóa (và cũng lưu tệp). Một chút của một tình huống bất thường, nhưng nó chắc chắn nhấn mạnh cho tôi những vấn đề với 'kiểm tra nếu tập tin bị khóa, sau đó mở nó nếu nó không' tiếp cận.
Sự cố là: tệp có thể bị khóa bị khóa giữa thời gian bạn kiểm tra và thời gian bạn thực sự mở tệp. Nó thực sự khó khăn để theo dõi các không thường xuyên Không thể sao chép các tập tin, bởi vì nó được sử dụng bởi một quá trình khác lỗi nếu bạn không tìm kiếm nó quá.
Độ phân giải cơ bản là chỉ cố gắng mở tệp bên trong khối catch để nếu khóa của nó, bạn có thể thử lại. Bằng cách đó không có thời gian trôi qua giữa kiểm tra và mở, hệ điều hành hiện chúng cùng một lúc.
Mã ở đây sử dụng Tệp.Sao chép, nhưng nó hoạt động ngang ngửa với bất kỳ phương pháp tĩnh của lớp File: File.Open, File.ReadAllText, File.WriteAllText vv
/// <param name="timeout">how long to keep trying in milliseconds</param>
static void safeCopy(string src, string dst, int timeout)
{
while (timeout > 0)
{
try
{
File.Copy(src, dst);
//don't forget to either return from the function or break out fo the while loop
break;
}
catch (IOException)
{
//you could do the sleep in here, but its probably a good idea to exit the error handler as soon as possible
}
Thread.Sleep(100);
//if its a very long wait this will acumulate very small errors.
//For most things it's probably fine, but if you need precision over a long time span, consider
// using some sort of timer or DateTime.Now as a better alternative
timeout -= 100;
}
}
Một lưu ý nhỏ trên parellelism: này là một phương thức đồng bộ, sẽ chặn luồng của nó cả trong khi đợi và trong khi làm việc trên luồng. Đây là cách tiếp cận đơn giản nhất, nhưng nếu tệp vẫn bị khóa trong một thời gian dài, chương trình của bạn có thể không phản hồi. Parellelism là một chủ đề quá lớn để đi vào chiều sâu ở đây, (và số cách bạn có thể thiết lập không đồng bộ đọc/ghi là loại vô lý) nhưng đây là một cách nó có thể được 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;
}
}
}
Và đây là cách nó có thể được sử dụng:
public static void Main()
{
test_FileEx();
Console.WriteLine("Me First!");
}
public static async void test_FileEx()
{
await Task.Delay(1);
//you can do this, but it gives a compiler warning because it can potentially return immediately without finishing the copy
//As a side note, if the file is not locked this will not return until the copy operation completes. Async functions run synchronously
//until the first 'await'. See the documentation for async: https://msdn.microsoft.com/en-us/library/hh156513.aspx
CopyWaitAsync("file1.txt", "file1.bat", 1000);
//this is the normal way of using this kind of async function. Execution of the following lines will always occur AFTER the copy finishes
await CopyWaitAsync("file1.txt", "file1.readme", 1000);
Console.WriteLine("file1.txt copied to file1.readme");
//The following line doesn't cause a compiler error, but it doesn't make any sense either.
ReadAllTextWaitAsync("file1.readme", 1000);
//To get the return value of the function, you have to use this function with the await keyword
string text = await ReadAllTextWaitAsync("file1.readme", 1000);
Console.WriteLine("file1.readme says: " + text);
}
//Output:
//Me First!
//file1.txt copied to file1.readme
//file1.readme says: Text to be duplicated!
Tôi tìm thấy câu trả lời ở đây xin lỗi [Vấn đề này được giải quyết trên Stackoverflow] [1] [1] : http://stackoverflow.com/questions/1406808/wait-for-file-to-be-freed-by-process – levi
bản sao có thể có của [Có cách nào để kiểm tra xem tệp có phải là tôi không n sử dụng?] (http://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use) –