的NetworkStream"不能访问一个释放的对象"使用新创建的NetworkStream时对象、NetworkStream、QUOT

2023-09-05 04:31:30 作者:傾聽ゝ小情歌

我有一个连接到远程主机几种不同的方法,发送邮件时,得到的答复,并利用这些信息。这一直很好,直到我用我的连接类的同一个实例的两种方法。在我得到错误的例子,我运行下面的方法;

I have a few different methods which connect to a remote host, send a message, get a reply, and use the information. this has worked fine until i use two methods in the same instance of my connection class. in the example where i'm getting the error, i run the following method;

public string sendRequestAccountID(string siteID)
{
    //build message
    String response = String.Empty;

    TcpClient client = new TcpClient();
    client.Connect(detailsHere);
    NetworkStream stream = client.GetStream();

    StreamWriter writer = new StreamWriter(stream);
    writer.AutoFlush = false;

    writer.WriteLine(sb.ToString());
    writer.Flush();

    StreamReader reader = new StreamReader(stream);
    List<XmlNode> nodeList = new List<XmlNode>();

    byte[] responseBytes = new byte[4096];
    int bytesRead = 0;

    while (true)
    {
        bytesRead = stream.Read(responseBytes, 0, responseBytes.Length);
        if (bytesRead > 0)
        {
            //handle message
        }
        if (bytesRead == 0)
        {
            stream.Flush();
            stream.Close();
            client.Close();
            string finalResponse = stuffHereToSend;
            return finalResponse;
        }
    }
}

这将罚款,并返回一个消息作为预期。但是,如果我再利用我的连接类的同一个实例,并使用下面的方法;

This sends fine, and returns a message as expected. However, if i then use the same instance of my connection class and use the following method;

public bool sendNewDevice(IDeviceInterface device)
{
    NetworkStream stream;
    sb = new StringBuilder();
    //build message
    String response = String.Empty;

    TcpClient client = new TcpClient();
    client.Connect(detailsHere);
    stream = client.GetStream();

    StreamWriter writer = new StreamWriter(stream);
    writer.AutoFlush = false;

    writer.WriteLine(sb.ToString());
    writer.Flush();

    StreamReader reader = new StreamReader(stream);
    List<XmlNode> nodeList = new List<XmlNode>();

    byte[] responseBytes = new byte[4096];
    int bytesRead = 0;

    while (true)
    {
        bytesRead = stream.Read(responseBytes, 0, responseBytes.Length);
        if (bytesRead > 0)
        { 
            //handle message
        }
    }
}

我收到其内容无法访问已释放的对象上的错误;

I'm getting an error which reads "cannot access a disposed object" on;

 bytesRead = stream.Read(responseBytes, 0, responseBytes.Length);

尽管我以为我会新增刚分配的最新方法的流。难道是想用previously封闭的?有没有解决的办法,或一些愚蠢的我失踪?

Although i thought that i'd newly just assigned the stream in the latest method. Is it trying to use the previously closed one? is there a way around this or something silly that i'm missing?

编辑:这是一些与客户不处理是否正确?这两种方法都在彼此的第二个跑了,也许是第二个尝试打开之前首先关闭了?

edit: is it something to with the clients not disposing correctly? the two methods are ran within a second of each other, maybe the second is trying to open before the first has closed?

推荐答案

的StreamWriter (与读写器)结束或其处置方法被调用,其配置基础流。此前.NET 4.5真的没有什么,你可以做些什么,除了使用其他东西比的StreamWriter 或写一个类来包装的StreamWriter ,而忽略调用处置。在.NET 4.5中,有一个过载,你可以用它来告诉的StreamWriter 不要丢弃你给它的流。例如:新的的StreamWriter(流StreamWriter.UTF8NoBOM,1024,FALSE)

When a StreamWriter (and reader) is closed or its Dispose method is called, it disposes the underlying stream. Prior to .net 4.5 there really wasn't anything you could do about it, other than use something other than StreamWriter or write a class to wrap the Stream given to StreamWriter and ignore the call to Dispose. in .NET 4.5, there is an overload you can use to tell the StreamWriter not to dispose the stream you give it. eg: new StreamWriter(stream, StreamWriter.UTF8NoBOM, 1024, false)

您可以尝试使用一个包裹流忽略关闭(调用新的StreamWriter(新NonDisposableStreamWrapper(流))):

You could try using a wrapped stream to ignore the close (calling new StreamWriter(new NonDisposableStreamWrapper(stream))):

public class NonDisposableStreamWrapper : Stream
{
    private Stream wrappedStream;

    public NonDisposableStreamWrapper(Stream wrappedStream)
    {
        this.wrappedStream = wrappedStream;
    }

    public override void Flush()
    {
        wrappedStream.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return wrappedStream.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        wrappedStream.SetLength(value);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return wrappedStream.Read(buffer, offset, count);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        wrappedStream.Write(buffer, offset, count);
    }

    public override bool CanRead
    {
        get { return wrappedStream.CanRead; }
    }

    public override bool CanSeek
    {
        get { return wrappedStream.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return wrappedStream.CanWrite; }
    }

    public override long Length
    {
        get { return wrappedStream.Length; }
    }

    public override long Position
    {
        get { return wrappedStream.Position; }
        set { wrappedStream.Position = value; }
    }
}