异常:无法访问已关闭的流(仅限 WinXP!)
Exception: cannot access a closed Stream (WinXP only!)
我正在为我的应用程序尝试 this TFTP 客户端作为客户端。但是,当有时我的程序试图读取流时抛出流已关闭的异常时,某处存在错误。在深入研究源代码后,我发现 TftpTransfer.cs
中有 Dispose 方法,有时会调用该方法然后抛出异常。
我找不到为什么有时会在我使用流之前调用 Dispose 方法(在 TFTP 传输完成后)以及如何解决它。
代码如下,设置position为0时出现异常
private static AutoResetEvent TransferFinishedEvent = new AutoResetEvent(false);
....
var client = new TftpClient("192.168.0.1");
var transfer = client.Download("00-02.conf");
transfer.OnFinished += new TftpEventHandler(transfer_OnFinshed);
transfer.OnError += new TftpErrorHandler(transfer_OnError);
Stream stream = new MemoryStream();
transfer.Start(stream);
TransferFinishedEvent.WaitOne();
stream.Position = 0;
var sr = new StreamReader(stream);
var myStr = sr.ReadToEnd();
Console.WriteLine(myStr);
...
static void transfer_OnError(ITftpTransfer transfer, TftpTransferError error)
{
Console.WriteLine("Transfer failed: " + error);
TransferFinishedEvent.Set();
}
static void transfer_OnFinshed(ITftpTransfer transfer)
{
Console.WriteLine("Transfer succeeded.");
TransferFinishedEvent.Set();
}
UPD:尚未奏效的解决方法
MemoryStream stream = new MemoryStream();
var sr = new StreamReader(new MemoryStream(stream.GetBuffer()));
transfer.Start(stream);
TransferFinishedEvent.WaitOne();
Console.WriteLine(sr.ReadToEnd());
sr
总是指向流的结尾并且它是空的。
UPD2:有一件事可能值得一提。异常无法访问已关闭的流仅发生在 Windows XP 框(我必须坚持使用的 .NET 3.5)上。我试过 Windows 7,尽管有时我看到框架内的流被处置,但我没有例外。同样,在 Windows 上,XP 异常随机发生。大约每 3 次调用我的应用程序就会抛出异常。
流在下载结束时似乎在库中被设计关闭。
//Was that the last block of data?
if (command.Bytes.Length < Context.BlockSize)
{
Context.RaiseOnFinished();
Context.SetState(new Closed());
}
Closed 状态只是在 TftpTransfer
的实例上调用 Dispose()
(这又关闭了流)。
我认为这可能是库中的一个错误 - 它不拥有流,所以它不应该关闭它,但你现在坚持使用它。
最简单的解决方案是创建一个新的内存流来读取这样捕获的字节::
var sr = new StreamReader(new MemoryStream(stream.GetBuffer());
我正在为我的应用程序尝试 this TFTP 客户端作为客户端。但是,当有时我的程序试图读取流时抛出流已关闭的异常时,某处存在错误。在深入研究源代码后,我发现 TftpTransfer.cs
中有 Dispose 方法,有时会调用该方法然后抛出异常。
我找不到为什么有时会在我使用流之前调用 Dispose 方法(在 TFTP 传输完成后)以及如何解决它。
代码如下,设置position为0时出现异常
private static AutoResetEvent TransferFinishedEvent = new AutoResetEvent(false);
....
var client = new TftpClient("192.168.0.1");
var transfer = client.Download("00-02.conf");
transfer.OnFinished += new TftpEventHandler(transfer_OnFinshed);
transfer.OnError += new TftpErrorHandler(transfer_OnError);
Stream stream = new MemoryStream();
transfer.Start(stream);
TransferFinishedEvent.WaitOne();
stream.Position = 0;
var sr = new StreamReader(stream);
var myStr = sr.ReadToEnd();
Console.WriteLine(myStr);
...
static void transfer_OnError(ITftpTransfer transfer, TftpTransferError error)
{
Console.WriteLine("Transfer failed: " + error);
TransferFinishedEvent.Set();
}
static void transfer_OnFinshed(ITftpTransfer transfer)
{
Console.WriteLine("Transfer succeeded.");
TransferFinishedEvent.Set();
}
UPD:尚未奏效的解决方法
MemoryStream stream = new MemoryStream();
var sr = new StreamReader(new MemoryStream(stream.GetBuffer()));
transfer.Start(stream);
TransferFinishedEvent.WaitOne();
Console.WriteLine(sr.ReadToEnd());
sr
总是指向流的结尾并且它是空的。
UPD2:有一件事可能值得一提。异常无法访问已关闭的流仅发生在 Windows XP 框(我必须坚持使用的 .NET 3.5)上。我试过 Windows 7,尽管有时我看到框架内的流被处置,但我没有例外。同样,在 Windows 上,XP 异常随机发生。大约每 3 次调用我的应用程序就会抛出异常。
流在下载结束时似乎在库中被设计关闭。
//Was that the last block of data?
if (command.Bytes.Length < Context.BlockSize)
{
Context.RaiseOnFinished();
Context.SetState(new Closed());
}
Closed 状态只是在 TftpTransfer
的实例上调用 Dispose()
(这又关闭了流)。
我认为这可能是库中的一个错误 - 它不拥有流,所以它不应该关闭它,但你现在坚持使用它。
最简单的解决方案是创建一个新的内存流来读取这样捕获的字节::
var sr = new StreamReader(new MemoryStream(stream.GetBuffer());