Tôi không phải là một fan hâm mộ lớn của try/catch IOException vì:
- Lý do cho sự ngoại lệ là không rõ.
- Tôi không thích các ngoại lệ 'được mong đợi' như tôi thường chạy với sự bẻ khóa.
Bạn có thể làm điều này mà không ngoại lệ bằng cách gọi CreateFile và trả về một dòng khi/nếu nó cuối cùng trả về một tay cầm:
public static System.IO.Stream WaitForExclusiveFileAccess(string filePath, int timeout)
{
IntPtr fHandle;
int errorCode;
DateTime start = DateTime.Now;
while(true)
{
fHandle = CreateFile(filePath, EFileAccess.GenericRead | EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero,
ECreationDisposition.OpenExisting, EFileAttributes.Normal, IntPtr.Zero);
if (fHandle != IntPtr.Zero && fHandle.ToInt64() != -1L)
return new System.IO.FileStream(fHandle, System.IO.FileAccess.ReadWrite, true);
errorCode = Marshal.GetLastWin32Error();
if (errorCode != ERROR_SHARING_VIOLATION)
break;
if (timeout >= 0 && (DateTime.Now - start).TotalMilliseconds > timeout)
break;
System.Threading.Thread.Sleep(100);
}
throw new System.IO.IOException(new System.ComponentModel.Win32Exception(errorCode).Message, errorCode);
}
#region Win32
const int ERROR_SHARING_VIOLATION = 32;
[Flags]
enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000
}
[Flags]
enum EFileShare : uint
{
None = 0x00000000,
}
enum ECreationDisposition : uint
{
OpenExisting = 3,
}
[Flags]
enum EFileAttributes : uint
{
Normal = 0x00000080,
}
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode)]
static extern IntPtr CreateFile(
string lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition dwCreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
#endregion
Nguồn
2010-09-27 23:45:55
đây có phải là tất cả các nơi tham gia trong một quá trình duy nhất? –
có. Nó thực sự đang được sử dụng trên Windows 7 Phone (Silverlight). – Micah