[英]Using BackgroundWorker WPF and getting error: Cannot access a disposed object
我对多线程还很陌生,因此请原谅可能出现的任何明显错误-我仍在学习!
我目前有一个程序,该程序使用TCPClient
和NetworkStream
从端口读取数据,并将数据输出到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_DoWork
和worker_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();
}
它在ReadInBytes
方法的以下行中fails
,并显示错误: 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();
}
client
和network stream
被声明为public statics
。 使用invoke
和不使用invoke
时,我都遇到了这个问题。 我也尝试了BeginInvoke
并且发生了相同的问题。 我们将不胜感激任何帮助以及对我哪里出错了的任何解释!
问题是,您将客户端放置在finally块中,但是在稍后运行的DoWork
方法中使用它。
要解决此问题,请在DoWork事件中创建,连接和克隆客户端:)。
如评论中所述,您不应在DoWork方法中分派代码! 只需致电ReadIn。 您想在后台运行代码,以使GUI保持可回收状态-将其推送到GUI线程毫无意义!
也不需要在RunWorkerCompleted事件处理程序中分派代码,因为后台工作会为您完成代码;)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.