对象处置异常
好吧,伙计们,我的代码中突然出现了一个以前没有出现过的问题。
public void StartUdpListener(Object state)
{
/* sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock1.Bind(receiveEndPoint);
EndPoint ep = (EndPoint)receiveEndPoint;*/
recv = sock1.ReceiveFrom(receivedNotification, ref ep);
notificationReceived = Encoding.ASCII.GetString(receivedNotification, 0, recv);
//sock1.Close();
if (listBox1.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
}
listBox.AppendLine(notificationReceived);
if (listBox1.InvokeRequired)
{
pos = listBox1.FindString(notificationReceived);
if (pos >= 0)
{
}
else
{
this.Invoke((MethodInvoker)delegate { this.listBox1.Items.Add(listBox.ToString()); });
}
}
}
我收到一个 ObjectDisposeException ,说该行:
this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
由于 listBox1 已释放而无法执行。这怎么可能,有什么需要做的吗?
Ok guys there is this sudden problem in my code which didn't appear before..
public void StartUdpListener(Object state)
{
/* sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock1.Bind(receiveEndPoint);
EndPoint ep = (EndPoint)receiveEndPoint;*/
recv = sock1.ReceiveFrom(receivedNotification, ref ep);
notificationReceived = Encoding.ASCII.GetString(receivedNotification, 0, recv);
//sock1.Close();
if (listBox1.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
}
listBox.AppendLine(notificationReceived);
if (listBox1.InvokeRequired)
{
pos = listBox1.FindString(notificationReceived);
if (pos >= 0)
{
}
else
{
this.Invoke((MethodInvoker)delegate { this.listBox1.Items.Add(listBox.ToString()); });
}
}
}
I am getting an ObjectDisposedException saying that the line:
this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
cannot be executed since listBox1 is disposed.How is that possible and is there anything that needs to be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我做出以下假设:
我猜想当表单关闭时,您的代码会阻塞套接字上的 receiveFrom() 调用。 从网络到达的下一条消息会导致 receiveFrom 返回,然后将收到的消息放入不再存在的列表框中。 第一次访问此列表框是创建 StringBuilder 时的代码行“this.listBox1.Text”,这是引发 ObjectDisposeException 的行。 listBox 是可能被处理的对象,尽管此时它也可能是 Form,具体取决于消息传入的速度。
似乎有很多事情需要完成,但我不确定什么是正确的建议。 我将首先验证上面的假设 1-4,然后考虑重构您的应用程序,使其不使用多线程。 我提出这个建议是因为我必须假设这不是您的应用程序可能遇到的唯一“线程”问题。 我的假设当然可能是错误的,在这种情况下你可以忽略答案。
如果我将问题的“需要做什么”部分限制在更有限的范围内,那么我建议在允许窗口关闭之前正确关闭 UDP 接收器,再次假设我的假设是正确的。
I am making the following assumptions:
I would guess that your code is blocking on the receiveFrom() call on the socket when the form is closed. The next message that arrives from the network causes receiveFrom to return, after which you put the message received into a listbox that no longer exists. The first time you access this listbox is code line "this.listBox1.Text" when creating the StringBuilder, which is the line that raises the ObjectDisposeException. The listBox is the object that is likely disposed, although it could also be the Form at this point, depening on how fast messages are coming in.
There appears to be plenty that needs to be done, but I am not sure what is proper advice. I would first validate my assumptions 1-4 above, then look into refactoring your application such that it does NOT use multiple threads. I make this suggestion because I must assume this is not the only "threading" issue your application may have. I certaintly may be incorrect in that assumption, in which case you can ignore the answer.
If I restrict the "what needs to be done" part of your question to a more limited scope, then I would advise to properly shutdown your UDP receiver before allowing the window to close, again assuming my assumptions are correct.
对此块的评论:
在执行 .AppendLine 时,StringBuilder(列表框)可能为空。 这是因为您在与使用列表框不同的线程中创建列表框。 此外,仅当此代码在非 UI 线程(这就是 listBox1.InvokeRequired)正在检查的上运行时,才会创建新的 StringBuilder 对象。
A comment on this block:
The StringBuilder (listbox) may be null at the point you do .AppendLine. This is because you are creating the listbox in a different thread to where you using it. Also a new StringBuilder object only gets created if this code is run on a non UI thread (thats what listBox1.InvokeRequired) is checking.