Using BackgroundWorker WPF and getting error: Cannot access a disposed object

Using BackgroundWorker WPF and getting error: Cannot access a disposed object

我对多线程还很陌生,因此请原谅可能存在的任何明显错误 - 我还在学习!

我目前有一个程序使用 TCPClientNetworkStream 从端口读取数据并将数据输出到 WPF 程序中的 text box。尽管如此,当尝试从 stream 中多次读取时,它会显着降低程序速度,并且需要读取的内容越多,程序打开所需的时间就越长。因此我决定尝试实施 threading 并尝试使用 Background Worker.

这是我在 MainWindow:

中的代码
InitializeComponent();

    try
    {
        client.Connect(address, port); //connect to the client 
        nwStream = client.GetStream(); //read in data from stream
        readInTxtBox.Text = ("Connection Open");
        BackgroundWorker worker = new BackgroundWorker(); 

        worker.DoWork += worker_DoWork; 
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.RunWorkerAsync();

    }
    catch (SocketException ex)
    {
        readInTxtBox.Text = ex.ToString(); //write out the error
    }
    finally
    {
        client.Close();
    }

这是 worker_DoWorkworker_RunWorkerCompleted 方法:

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    if (Dispatcher.CheckAccess())
    {
        ReadIn();
    }
    else
    {
        Dispatcher.BeginInvoke(new Action(() =>
        {
            ReadIn();
        }));
    }
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    Dispatcher.BeginInvoke(new Action(() =>
    {
        OutputToTextBoxInput();

    }));

}

单步执行时,它会转到 worker_DoWork 上的 Dispatcher.BeginInvoke 操作,并在 ReadIn() 方法的第一行失败:

private void ReadIn()
{
    byte[] b = Utilities.ReadInBytes(client, nwStream); //fails here!
    hex = Utilities.ConvertByteToHex(b);
    nwStream.Close();
}

failsReadInBytes 方法的下一行,错误:Cannot access a disposed object.

public static byte[] ReadInBytes(TcpClient client, NetworkStream nwStream)
{
    byte[] bytesToRead = new byte[client.ReceiveBufferSize]; //FAILS HERE
    int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
    ArraySegment<byte> segment = new ArraySegment<byte>(bytesToRead, 0, bytesRead);

    return segment.ToArray();
} 

clientnetwork stream 声明为 public statics。我在使用 invoke 和不使用时遇到过这个问题。我也试过 BeginInvoke 也出现了同样的问题。 任何帮助以及对我哪里出错的任何解释都将不胜感激!

问题是,您在 finally 块中处理客户端,但在 运行ning 之后的 DoWork 方法中使用它。

要解决它,请在 DoWork 事件中创建、连接和关闭客户端:)。


如评论中所述,您不应在 DoWork 方法中分派代码!只需在那里调用 ReadIn。您想要 运行 后台代码,以便 GUI 保持可响应 - 将它推送到 GUI 线程是没有意义的!

也不需要分派 RunWorkerCompleted 事件处理程序中的代码,因为后台工作会为您完成 ;)。