步骤是这样的。
点击一个按钮然后开始异步委托执行一个循环。
在循环中会访问到界面中的控件,由于是不同线程,需要唤起ui线程。public void SetValueFun(string str, string controlid, object form1)
        {
            Form1 f1 = form1 as Form1;
            if (this.InvokeRequired)
            {
                f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
            }
            else
            {
                f1.Controls[controlid].Text = str;
            }
        }然后会抱无法访问已释放的对象。对象名:“Form1”。
该怎么解决?知道问题出在哪,是因为窗体关闭了,但还是在继续执行。
试过了
if(f1.isDisposed)
  return;
还是不行。

解决方案 »

  1.   

    建议定义form1为一个静态变量,然后多个线程都可以访问
      

  2.   

    你用BeginInvoke试一下,Invoke是同步方法。
      

  3.   

    还有你的InvokeRequired对象不是from,而是 f1.Controls[controlid]
      

  4.   

    异步我不是用在这里,FunKids funkids = new FunKids(GetNext);
                AsyncCallback callBack = new AsyncCallback(FunKidsCallBack);
                funkids.BeginInvoke(star, true, true, callBack, "处理结束");我这里有用了异步,GetNext这个方法是一form循环。
    循环处理的结果然后显示在控件上,由于和ui不同线程,所以需要Invoke唤起ui线程显示到ui界面中的控件上。
    然后如果还没循环完就关闭窗体就抱了刚才那个错。
      

  5.   

    我改成f1的了 还是不行。        public void SetValueFun(string str, string controlid, object form1)
            {
                Form1 f1 = form1 as Form1;
                if (f1.InvokeRequired)
                {
                    f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
                }
                else
                {
                    f1.Controls[controlid].Text = str;
                }
            }
      

  6.   

    定位到f1.Controls[controlid].InvokeRequired呢
      

  7.   


    if(f1!=null&&!f1.IsDisposed)
    {
     if (f1.InvokeRequired)
                {
                    f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
                }
                else
                {
                    f1.Controls[controlid].Text = str;
                }
    }
      

  8.   

    那就这样,在 Form1 中定义一个标记变量 flag 默认 true在Form1 关闭的时候 置为false然后if(f1!=null&&f1.flag)
    {
     if (f1.InvokeRequired)
                {
                    f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
                }
                else
                {
                    f1.Controls[controlid].Text = str;
                }
    }
      

  9.   

    那你这个form1也做一个是否为null或者isdisposed的判断
      

  10.   

    我SetValueFun是这样调用的。//result是处理后的数据。
    SetValueFun(result, "txt_Content", this);
      

  11.   

    SetValueFun 内部能使用 this 么 ?  this 是 Form1 么?if(f1!=null&&!f1.IsDisposed)=>if(this!=null&&!this.IsDisposed)应该调用 this
    如果上面的不行,就把flag定义成静态的
      

  12.   

    我本来就是用this,然后不行,然后看了这篇文章
    http://www.cnblogs.com/yibinboy/archive/2009/12/26/1633066.html
    然后改成f1的。
      

  13.   

    可以使用this,我断点调试了看下,this指的是kids.Form1
      

  14.   

    我刚试了下, !this.IsDisposed是可以的。 
      

  15.   

    奇怪 我怎么不行,我把我的那个问题抽离了出来。页面上只有一个button按钮,还有一个listbox控件。然后代码如下,非哥 麻烦在帮忙看下。    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 < 10000; i++)
                {
                    SetListBox(i);
                    Thread.Sleep(100);
                }
            }
        }
      

  16.   

      MessageBox.Show(result.AsyncState.ToString());
     这句话去掉,会引起阻塞。
      

  17.   

    SetListBox(i);
                    Thread.Sleep(100);这两句换下位置Thread.Sleep(5000);
    SetListBox(i);窗体展示后 马上关闭。然后断点点在这句上 if (this != null && !this.IsDisposed)
      

  18.   

    this.Isdisposed是false,不过我是按下按钮调式的。
    因为一展开窗体,就关闭,就不执行里面的代码。
    而一展开,按下按钮,就只有等执行完了后才能按关闭的X按钮。
      

  19.   

    不好意思 非哥,刚没注意看你Sleep时间变长。
    我改成这样
                    Thread.Sleep(5000);
                    SetListBox(i);
    然后一按下按钮,就关闭窗体,然后断点在
    if (this != null && !this.IsDisposed)
    这句
    没进断点里额。
      

  20.   

    你的代码是通过 Delegate.BeginInvoke调用的,我测试的代码是 Control.Invoke 调用的。这两个是有差异,我是准备最后不行了再让你换那种方案。我只是想确认一下 ,你现在的问题怎么解决
      

  21.   

    是这样的,我一点按钮执行,然后关闭窗体,然后就抱错,查看IsDisposed,发现IsDisposed为false。
    不知道非哥是不是叫我这样做。
      

  22.   

    非哥,麻烦了你一下午了,真不好意思。
    我发现了点。
    如果把 this.Invoke(new SetValue(SetListBox), i);
    改为
    this.BeginInvoke(new SetValue(SetListBox), i);
    就不会抱错。正常关闭。
    只是不知道其中是什么原因。
      

  23.   

    设置大点的话,如果还没到5秒的时候就关闭的话不会执行它下面的
    SetListBox(i);这个方法额。断点在if (this != null && !this.IsDisposed)这句没反映。
      

  24.   

    如果把 this.Invoke(new SetValue(SetListBox), i);
    改为
    this.BeginInvoke(new SetValue(SetListBox), i);
    就不会抱错。正常关闭。
    只是不知道其中是什么原因。
    ----------------------------------------------
    刚看了下,差异在if (!synchronous)
        {
            return entry;
        }
        if (!entry.IsCompleted)
        {
            this.WaitForWaitHandle(entry.AsyncWaitHandle);
        }
        if (entry.exception != null)
        {
            throw entry.exception;
        }
        return entry.retVal;Invoke 时synchronous 为true
    BeginInvoke 时 synchronous 为false就是说BeginInvoke 没有处理异常,所以没有报错。
      

  25.   

    那段代码是Control的MarshaledInvoke方法
    private object MarshaledInvoke(Control caller, Delegate method, object[] args, bool synchronous)反编译查看。