[英]Using BackgroundWorker WPF and getting error: Cannot access a disposed object
I am fairly new to multi threading, therefore please excuse any obvious mistakes which may be present - I am still learning! 我对多线程还很陌生,因此请原谅可能出现的任何明显错误-我仍在学习!
I currently have a program which reads in from a port using TCPClient
and NetworkStream
and outputs the data to a text box
in a WPF program. 我目前有一个程序,该程序使用
TCPClient
和NetworkStream
从端口读取数据,并将数据输出到WPF程序中的text box
。 Nonetheless, when trying to read in multiple times from the stream
, it slows the program down quite noticeably and the more it has to read, the longer it takes for the program to open. 但是,当尝试从
stream
中多次读取时,它会明显降低程序运行速度,并且读取的次数越多,打开程序所花费的时间就越长。 Therefore I decided to try and implement threading
and I am trying to use Background Worker
. 因此,我决定尝试实现
threading
并且尝试使用Background Worker
。
Here is the code I have in the MainWindow
: 这是我在
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();
}
This is the worker_DoWork
and worker_RunWorkerCompleted
methods: 这是
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();
}));
}
When stepping through, it does go to the Dispatcher.BeginInvoke
action on the worker_DoWork
, and fails on the first line of the ReadIn()
method : 单步执行时,它确实转到
worker_DoWork
上的Dispatcher.BeginInvoke
操作,并在ReadIn()
方法的第一行失败:
private void ReadIn()
{
byte[] b = Utilities.ReadInBytes(client, nwStream); //fails here!
hex = Utilities.ConvertByteToHex(b);
nwStream.Close();
}
It fails
on the following line of the ReadInBytes
method, with the error: Cannot access a disposed object.
它在
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();
}
The client
and network stream
are declared as public statics
. client
和network stream
被声明为public statics
。 I have had this problem when using invoke
and when not. 使用
invoke
和不使用invoke
时,我都遇到了这个问题。 I have also tried BeginInvoke
and the same problem has occurred. 我也尝试了
BeginInvoke
并且发生了相同的问题。 Any help would be massively appreciated as well as any explanations on where I have gone wrong! 我们将不胜感激任何帮助以及对我哪里出错了的任何解释!
The problem is, that you dispose the client in the finally block, but use it in the DoWork
methods which is running later. 问题是,您将客户端放置在finally块中,但是在稍后运行的
DoWork
方法中使用它。
To solve it, create, connect and clode the client in the DoWork event :). 要解决此问题,请在DoWork事件中创建,连接和克隆客户端:)。
As mentioned in a comment, you should not dispatch your code in the DoWork method! 如评论中所述,您不应在DoWork方法中分派代码! Just call ReadIn there.
只需致电ReadIn。 You want to run the code in background, so that the GUI remains resposable - it makes no sense to push it to the GUI thread!
您想在后台运行代码,以使GUI保持可回收状态-将其推送到GUI线程毫无意义!
It is also not required to dispatch the code in the RunWorkerCompleted event handler, because the background work does it for you ;). 也不需要在RunWorkerCompleted事件处理程序中分派代码,因为后台工作会为您完成代码;)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.