我正在编写一个C#应用程序(限于.NET framework 4.0或更低版本(即没有Read / WriteAsync)),负责在Windows(7或更高版本)机器和NFS安装的Unix之间读/写文件基于服务器。
客户端计算机是移动的,并且预计会定期与网络断开连接。因此,我希望强化我的应用程序,以便在读取或写入操作过程中优雅地处理断开连接(希望是偶然的)。
为了跟踪是否发生超时,我异步读取(或写入)并使用AsyncWaitHandle
返回的IAsyncResult
的{{1}}:
FileStream.BeginRead
出现问题的原因是在超时的情况下清理我的溪流。在断开连接时,似乎在流上调用private int PerformRead (FileStream readStream,
byte [] buffer,
int nBytes)
{
IAsyncResult readResult = null;
try
{
readResult = readStream.BeginRead
(buffer, 0, nBytes, null, null);
// If the read was completed, return # of bytes read.
if (readResult.AsyncWaitHandle.WaitOne (1000))
{
return readStream.EndRead (readResult);
}
// Otherwise, the timeout has elapsed.
else
{
throw new TimeoutException ();
}
}
finally
{
if (null != readResult)
{
readResult.AsyncWaitHandle.Close ();
}
}
}
或Dispose()
会无限期挂起。为了解决这个问题,我在超时时明确地在文件句柄上调用Win32的Close()
。在切断连接时,此功能似乎也会阻塞。以下代表我对读取流的处理。
CloseHandle()
是否有推荐的方法为不再可用的文件正确处理FileStream?请注意,如果连接已断开,对private void ReadNewFile (string path,
byte [] buffer)
{
IntPtr readHandle = IntPtr.Zero;
FileStream readStream = null;
try
{
readHandle = CreateFile (path
0xc0000000,
0,
IntPtr.Zero,
3,
0x40000000,
IntPtr.Zero);
SafeFileHandle safeReadHandle = new SafeFileHandle (readHandle, true);
if (safeReadHandle.IsInvalid)
{
throw new Exception ();
}
readStream = new FileStream (safeReadHandle,
FileAccess.Read,
4092,
true);
while (true)
{
// Read part of the file into the buffer.
int bytesRead = PerformRead (readStream, buffer, buffer.Length);
// If EOF reached, break.
if (bytesRead == 0)
{
break;
}
}
}
catch (TimeoutException)
{
// NOTE: Hangs indefinitely if the network cable is unplugged.
CloseHandle (readHandle);
}
finally
{
if (null != readStream)
{
// NOTE: Hangs indefinitely if both of the following are true:
// - Network cable is unplugged (resulting in TimeoutException)
// - The body of the caught TimeoutException is commented out.
readStream.Close ();
}
}
}
的任何调用也将无限期挂起。