**********100分问题异步委托抱错的问题******************

tiandiyuzhou2 2011-11-08 09:03:12
把从项目中的问题抽离出来,界面中有个listbox控件和button控件

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate void FunDelegate();
public delegate void SetValue(int i);
private void button1_Click(object sender, EventArgs e)
{
FunDelegate fundelegate = new FunDelegate(FunProc);
AsyncCallback callback = new AsyncCallback(CallBack);
IAsyncResult result = fundelegate.BeginInvoke(callback, "处理结束");
}
public void CallBack(IAsyncResult result)
{
MessageBox.Show(result.AsyncState.ToString());
}
public void SetListBox(int i)
{
if (this != null && !this.IsDisposed)
{
if (this.InvokeRequired)
{
this.Invoke(new SetValue(SetListBox), i);
}
else
{
listBox1.Items.Add(i);
}
}
}
public void FunProc()
{
for (int i = 0; i < 5000; i++)
{
Thread.Sleep(100);
SetListBox(i);
}
}
}

以上代码,如果在委托未处理结束的时候就关闭窗体,
会抱错:
无法访问已释放的对象。
对象名:“Form1”。

该怎么解决呢?
如果把
this.Invoke(new SetValue(SetListBox), i);
改成=》
this.BeginInvoke(new SetValue(SetListBox), i);
确实不会抱错,不反编译了下,BeginInvoke不会抱错是因为直接返回,没有抛出异常。
这样不能根本的解决问题。

请问该怎么解决?大家可以自己试一下。
...全文
660 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sandy945 的回复:]
无视错误。强退
[/Quote]非哥 谢谢你,又麻烦了你一早上。
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
在看看有没有柔和点的方法,
如果没有的话就只能这样强制退出,或者用Control.beginInvole无视异常了。
阿非 2011-11-08
  • 打赏
  • 举报
回复
无视错误。强退
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sandy945 的回复:]
强制退出的办法是

C# code

System.Environment.Exit(-1);


写在窗体的关闭事件中Form_FormClosing,缺点是过于暴力。
[/Quote]确实很暴力,请问下用这个暴力退出有什么影响或弊端吗?
阿非 2011-11-08
  • 打赏
  • 举报
回复
强制退出的办法是

System.Environment.Exit(-1);

写在窗体的关闭事件中Form_FormClosing,缺点是过于暴力。
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 sandy945 的回复:]
可能我问的不准确,换个问法。

this.Invoke 会出现几次,在你现在的示例中会多次,因为在循环中。

实际中可能只需要一次。处理办法是不一样的。

退出的时候 可以强制退出么?
[/Quote]

1:退出的时候可以强制退出,也就是用户在处理的时候可以不让它全部处理完就退出。
2:
invoke会出现几次:
现在我的做法是会出现很多次,非哥帮我看下是不是能出现一次,我说下我的思路
用户输入开始id,结束id,然后循环这中间的差值。
在循环中,根据id去获取数据库中的内容,然后在把内容处理显示到richtextbox上,
并把处理结果(是否相同内容,相同内容不处理,不相同内容处理成功)显示到listbox上。
由于我用了Delegate.BeginInvoke异步委托执行,所以当要访问控件的时候,需要this.Invoke唤起ui线程。

这是我的理解以及我的做法,非哥麻烦看下。
阿非 2011-11-08
  • 打赏
  • 举报
回复
可能我问的不准确,换个问法。

this.Invoke 会出现几次,在你现在的示例中会多次,因为在循环中。

实际中可能只需要一次。处理办法是不一样的。

退出的时候 可以强制退出么?
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
然后把值显示到控件上
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
实际情况是这样的。
就是有个范围,然后循环这个范围内的值。
然后因为是用了委托的BeginInvoke,所以要访问ui线程上的控件就需要在this.Invoke唤起ui线程。
然后在显示控件上的值

退出的话我是想不抱异常,正常退出。
阿非 2011-11-08
  • 打赏
  • 举报
回复
实际中 会有循环设置value 这个情况么?

你希望退出时,直接退出还是怎么
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 javabegin 的回复:]
那就等他执行完了,再关闭窗体。
用AutoRestEvent。关闭窗体事件中调用WaitOne方法。
FunProc中循环执行完调用Set方法.
[/Quote]可以详细点吗?就上面例子该怎么改?
javabegin 2011-11-08
  • 打赏
  • 举报
回复
那就等他执行完了,再关闭窗体。
用AutoRestEvent。关闭窗体事件中调用WaitOne方法。
FunProc中循环执行完调用Set方法.
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
google查遍了还是木有解决额。
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bdmh 的回复:]
Invoke改为BeginInvoke(异步),不推荐这样做

所以还是做好同步
[/Quote]恩 我也是不推荐
this.Invoke(new SetValue(SetListBox), i);
改成=》
this.BeginInvoke(new SetValue(SetListBox), i);这样做。

不过Invoke的话会抱错,这个问题困扰了我好多天了,还没解决,该怎么解决?
bdmh 2011-11-08
  • 打赏
  • 举报
回复
Invoke改为BeginInvoke(异步),不推荐这样做

所以还是做好同步
liukaizxc 2011-11-08
  • 打赏
  • 举报
回复
你设置断点 看下 Form1 类 什么时候被销毁的 找下 问题正确地方
阿非 2011-11-08
  • 打赏
  • 举报
回复
tiandiyuzhou2 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 sgzhou12345 的回复:]
你踊跃测试一下将错误传上来
[/Quote]额 错误就是
无法访问已释放的对象。
对象名:“Form1”。
山东蓝鸟贵薪 2011-11-08
  • 打赏
  • 举报
回复
你踊跃测试一下将错误传上来
加载更多回复(9)

110,534

社区成员

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

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

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