以下两行代码依次执行:
this.dataWriter.WriteBytes(message.MessageBuffer);
await this.dataWriter.StoreAsync();
虽然WriteBytes
调用毫无例外地完成,但StoreAsync
下面的ObjectDisposedException
电话会以this.DataWriter
进行轰炸并说
该对象已关闭。 (HRESULT异常:0x80000013)
this.socket = new StreamSocketListener();
this.socket.ConnectionReceived += this.EventSocketConnectionReceived;
private void EventSocketConnectionReceived(StreamSocketListener sender,
StreamSocketListenerConnectionReceivedEventArgs args)
{
if (this.dataWriter == null)
{
this.dataWriter = new DataWriter(args.Socket.OutputStream);
}
}
( Windows.Storage.Streams.DataWriter )不为空,所以究竟是什么说"关闭?"
修改
仅针对如何创建对象的进一步背景
11/1/15 11/2/15 11/3/15 11/4/15
Type1 1 2 1 3
Type2 A C D B
答案 0 :(得分:3)
我没有Windows.Storage.Streams.DataWriter
的经验,但我的赌注是你将它传递给一个流,然后关闭它,然后调用它。它可能不是dataWriter
甚至抛出异常,虽然看一下Stack Trace会告诉你。
此代码会导致此错误,这是一个非常容易犯的错误:
Windows.Storage.Streams.DataWriter dataWriter;
using (var file = File.OpenRead("..."))
{
dataWriter = new DataWriter(file);
}
dataWriter.WriteBytes(message.MessageBuffer);
await dataWriter.StoreAsync();
处置与null
几乎无关。与处置的东西很少有关系,因此我们将其设为null,但这不是必需的。
我会检查你正在传递给构造函数的流,然后查找可能正在处理它的那个流的任何引用(通过像我在这里展示的using
块,或者显式调用stream.Dispose()
)。
有一个无限的组合线来抛出它,你所拥有的东西不太可能像我在这里说的那样简单(它可能分散在构造函数和方法中,并与不相关的代码混合在一起)。但我几乎可以保证它就像这种模式。
因为听起来有些分歧,所以问题在于difficult to tell if something is disposed没有告诉它做某事。
由于DataWriter
实质上是缓存操作,因此在您调用StoreAsync()
之前,它不会与基础流进行通信。这就是为什么WriteBytes
也不是异步的原因。您可以想象一个实现只是将它们固定在List<byte>
上(当然,它会比这复杂得多)。
但是当你调用StoreAsync()
方法时,它会联系到流并说“写下我已经缓存的东西”。流尝试,但它已经关闭,所以它抛出了异常。
这就是为什么它不会抛出第一行,而是在第二行。为什么我怀疑这是一个被处理的流,与DataWriter
本身被处置相比。
根据您的编辑和评论,您的信息流来自事件参数。
我的猜测是事件调用者正在关闭流,否则远程客户端将关闭套接字(可能是由于超时?)。我不知道是否有正确的方法来保持该流,如果它是前者。但那可能就是你应该把你的研究时间放在哪里。