无法访问以释放的对象 求解决 #c

wy3792 2010-07-03 09:42:03
程序没有错误但是在运行结束是会提示无法访问以释放的对象


未处理 System.ObjectDisposedException
Message="无法访问已释放的对象。\r\n对象名:“FormP2P”。"
Source="System.Windows.Forms"
ObjectName="FormP2P"
StackTrace:
在 System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
在 System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
在 P2PExample.FormP2P.ShowMyMessage(String str) 位置 G:\网络通信\P2PExample\P2PExample\FormP2P.cs:行号 152
在 P2PExample.FormP2P.Listening() 位置 G:\网络通信\P2PExample\P2PExample\FormP2P.cs:行号 101
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException:

代码如下:
private void ShowMyMessage(string str)
{
//比较调用的线程和创建的线程是否为同一线程
//如果不是,结果为true
if (this.listBoxMessage.InvokeRequired == true)
{
//如果结果为true,则自动通过代理执行else中语句的功能(注意:是else不是IF)
//这里只需要传入参数Str即可
//但是执行的功能会始终与else中的指定的功能相同,区别仅是通过代理完成
ShowMessageDelegatel messageDelegate = new ShowMessageDelegatel(ShowMyMessage);
this.Invoke(messageDelegate, new object[] { str });-----------------这行运行结束时报错
}
else
{
//在这里指定如果是同一个线程需要完成什么功能
//如果是不同的线程,系统会自动通过代理实现这里指定的功能
listBoxMessage.Items.Add(str);
}
...全文
1019 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
wy3792 2010-07-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wuyq11 的回复:]

试图操作已释放的对象会引发 ObjectDisposedException
加try catch
或判断null
传递对象到方法Invoke(new MethodInvoke(a),frm1 );
[/Quote]

可以写一下么 我小白 调试别人程序很无奈。。。
wuyq11 2010-07-03
  • 打赏
  • 举报
回复
试图操作已释放的对象会引发 ObjectDisposedException
加try catch
或判断null
传递对象到方法Invoke(new MethodInvoke(a),frm1 );
满衣兄 2010-07-03
  • 打赏
  • 举报
回复
这个问题与C#的垃圾回收有关。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C#对象没有确定性毁坏。所以会出现子窗口对象已被销毁,但又不为null,故出现访问时产生“未处理 ObjectDisposedException”异常(来自于“从小处看C#.net垃圾回收”一文)。
满衣兄 2010-07-03
  • 打赏
  • 举报
回复
1.这么写看看
ShowMessageDelegatel messageDelegate = new ShowMessageDelegatel(ShowMyMessage);
object[] arg = new object[] { str };//要传入的参数值
this.Invoke(messageDelegate, arg);
2。如果1不行,把 ShowMessageDelegatel messageDelegate写成类成员变量看看
兔子-顾问 2010-07-03
  • 打赏
  • 举报
回复
System.ObjectDisposedException
比如窗体资源点关闭后,线程判断有效而执行了Invoke就会出现,这个异常是正常的,需要你捕获的。

private void ShowMyMessage(string str)
{
try
{
//比较调用的线程和创建的线程是否为同一线程
//如果不是,结果为true
if (this.listBoxMessage.InvokeRequired == true)
{
//如果结果为true,则自动通过代理执行else中语句的功能(注意:是else不是IF)
//这里只需要传入参数Str即可
//但是执行的功能会始终与else中的指定的功能相同,区别仅是通过代理完成
ShowMessageDelegatel messageDelegate = new ShowMessageDelegatel(ShowMyMessage);
this.Invoke(messageDelegate, new object[] { str });-----------------这行运行结束时报错
}
else
{
//在这里指定如果是同一个线程需要完成什么功能
//如果是不同的线程,系统会自动通过代理实现这里指定的功能
listBoxMessage.Items.Add(str);
}
}
catch(System.ObjectDisposedException)
{
return;//如果主界面已经退出了,那线程也退出好了。
}
}

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧