以下的代码是框架上的一个控件,实现目的是异步调用方法刷新控件 。
这段类似的代码在主窗口上运行没问题。而在控件上则等不到异步调用的完成。望高手指点哦~main() {  
CallMsg();
        }        delegate void FressTalk();
 
        public void CallMsg() 
        {
            Thread th1 = new Thread(new ThreadStart(AsyncCall_In_MsgRefess));
            th1.IsBackground = true;
            th1.Name = "th1";
            th1.Start();  
        }
        private void AsyncCall_In_MsgRefess()
        {   
            System.Timers.Timer fressMsgTimer = new System.Timers.Timer(6000); //(new TimerCallback(TimerWork), null, 3000, 3000);
            fressMsgTimer.Elapsed += new System.Timers.ElapsedEventHandler(TimerWork);
            fressMsgTimer.AutoReset = true; 
            fressMsgTimer.Enabled = true;         }        private void TimerWork(object sender, ElapsedEventArgs e)
        {            if (wb.InvokeRequired) //wb是一个浏览器控件,
            {
                FressTalk FressMsg = new FressTalk(tmrGetMsg_Tick); 
                //BeginInvoke(FressMsg); 如果我这样调用,也是可以的,但是会阻塞,界面就卡                IAsyncResult ar = FressMsg.BeginInvoke(null, null);
                while (!ar.IsCompleted)
                {   
                    Thread.Sleep(100); 
                }
                 ////执行到这里,一直等不到ar的结束,十分怪异
                FressMsg.EndInvoke(ar);
              
            }
            
        }
 
 
        private void   tmrGetMsg_Tick()
        {
         //这里的代码是读取web服务,刷新框架的控件
}

解决方案 »

  1.   

     FressMsg.EndInvoke(ar);在异步调用的回调函数中调用试试。               AsyncCallback acb = new AsyncCallback(CallBackMethod);
                   //异步开始
                   //如果参数acb换成null则表示没有回调方法
                   //最后一个参数dn的地方,可以换成任意对象,该对象可以被回调方法从参数中获取出来,写成null也可以。参数dn相当于该线程的ID,如果有多个异步线程,可以都是null,但是绝对不能一样,不能是同一个object,否则异常
                   IAsyncResult iar = dn.BeginInvoke(1, out i, acb, dn);//程序终点
    //异步完成时,执行的方法(回调方法),此方法只能有IAsyncResult一个参数,但是该参数几乎万能,可以传递object
    private void CallBackMethod(IAsyncResult ar)
    {
                   //从异步状态ar.AsyncState中,获取委托对象
                   DelegateName dn = (DelegateName)ar.AsyncState;
                   //输出参数
                   int i;               //一定要EndInvoke,否则你的下场很惨
                   string r = dn.EndInvoke(out i, ar);
                   MessageBox.Show("异步完成喽!i的值是" i.ToString() ",r的值是" r);
    }
      

  2.   

    你这个代码我看过了,这是使用回调的方法。
    我使用这个的使用会产生错误, if (wb.InvokeRequired)
                {
                    FressTalk FressMsg = new FressTalk(tmrGetMsg_Tick);                  IAsyncResult ar = FressMsg.BeginInvoke(CallBackMethod, FressMsg); 
                }
            }        private void CallBackMethod(IAsyncResult ar)
    {
       
      FressTalk dn = (FressTalk)ar.AsyncState;
      
      dn.EndInvoke(ar);   ///这里出错,"指定的转换无效。"},不知为何 ???
      

  3.   

    没调试过,还有你的  if (wb.InvokeRequired)在使用wb这个控件时也应该使用委托:
            public void AsyncCall_In_MsgRefess()
            {
                if (this.wb.InvokeRequired)
                {
                    MyInvoke _myinvoke = new MyInvoke(AsyncCall_In_MsgRefess); //MyInvoke是一个委托
                    this.Invoke(_myinvoke);
                }
                else
                {
                 FressTalk FressMsg = new FressTalk(tmrGetMsg_Tick);  
                 IAsyncResult ar = FressMsg.BeginInvoke(null, null);
                 while (!ar.IsCompleted)
                    {   
                      Thread.Sleep(100);  
                    }
                  ////执行到这里,一直等不到ar的结束,十分怪异
                    FressMsg.EndInvoke(ar);
                }
            }
      
      

  4.   

    private deldgate void MyInvoke();//委托如果不行,再看看其他人的解决方案吧~
      

  5.   

    IAsyncResult ar = FressMsg.BeginInvoke(null, null);将上面的代码改为
    IAsyncResult ar = wb.BeginInvoke(FressMsg, null);//wb 是你的控件名字.FressMsg.EndInvoke(ar);
    改为
    wb.EndInvoke(ar);试试.
      

  6.   

    谢谢各位,我的问题解决了,不过我还不太清楚是怎么回事。
    办法就是 tmrGetMsg_Tick()里面对控件操作的方法也使用委托加invoke。
    8楼说的方法 我再试试看
      

  7.   


    试了不行~  还是要用到控件的时候用委托invoke。