本来的想法。2个窗体,一个主窗体,一个现实进度的窗体。我的代码。private delegate void OrderInvoke(); // 声明委托private void _Invoke()
{
    try
            {
                OrderInvoke oi      = new OrderInvoke(OrderDepartmentCDOne);//要执行的方法。
        
                frmsplash           = new frmSplash();                      // 进度窗体
                oi.BeginInvoke(new AsyncCallback(_EndInvoke),null);
                if(frmsplash != null)
                {
                    frmsplash.ShowDialog(this);
                    frmsplash.Dispose();
                }
            }
            catch(System.NullReferenceException ex )
            {
                MessageBox.Show("_Invoke"+ex.Message);
            }
        }
        private void _EndInvoke(IAsyncResult ar)
        {
            try
            {
                OrderInvoke oi = (OrderInvoke)((System.Runtime.Remoting.Messaging.AsyncResult)ar).AsyncDelegate;
                oi.EndInvoke(ar);
                frmsplash.Close();
            }
            catch(Exception ex )
            {
                MessageBox.Show("_EndInvoke"+ex.Message);
            }
        }        private void OrderDepartmentCDOne() // 测试用的方法。
        {
            frmsplash.prbMax = 499;    //ProcessBar的Maxmum
            for(int i = 0 ;i< this.fpSpread1.Sheets[0].Rows.Count; i++)
            {
                if(i == 499)
                {
                    break;
                }
                frmsplash.prbValue = i+1; //ProcessBar的Value
                System.Threading.Thread.Sleep(100);
                this.fpSpread1.Sheets[0].Rows[i].BackColor = System.Drawing.Color.Blue;//这里用的是Spread的控件
            }             
        }
        
再OrderDepartmentCDOne方法中,向进度窗体传值
以上贴出的代码可以顺利执行。OrderDepartmentCDOne里变成我真正要写的代码(有一个循环,每循环一次  参照数据库做一个Check,还有挺多复杂的判断)
这个OrderDepartmentCDOne方法单独执行,没有错误。但是用了委托异步调用的时候,编译过后的第一次执行中,会报一个对象没有被实例化的错误。也只能在private void _Invoke()里捕捉到这个错误。
出错之后,进度窗体关闭。 OrderDepartmentCDOne方法继续执行。再次执行多次也不会再出错,都能顺利完成了。各位大大,给分析下,是哪个地方出现问题了,实在找不出来。OrderDepartmentCDOne 要循环多次,目前测试时1000次左右。

解决方案 »

  1.   

    OrderInvoke oi      = new OrderInvoke(OrderDepartmentCDOne);//要执行的方法。
           
                    frmsplash           = new frmSplash();                      // 进度窗体
    -----------------------------------------------------------
              frmsplash           = new frmSplash();                      // 进度窗体
    OrderInvoke oi      = new OrderInvoke(OrderDepartmentCDOne);//要执行的方法。调换下顺序,进度窗体要先实例化.
            
          
      

  2.   

    谢谢ls的,但是不是这个问题。 
    错误是在OrderDepartmentCDOne 里很复杂的情况下发生,
    但是我单独执行OrderDepartmentCDOne 是没有错误的。
      

  3.   

    哦,那你试试锁下资源:private void OrderDepartmentCDOne() // 测试用的方法。
            {
             lock(frmsplash)//fpSpread1
             {
                frmsplash.prbMax = 499;    //ProcessBar的Maxmum
                for(int i = 0 ;i< this.fpSpread1.Sheets[0].Rows.Count; i++)
                {
                    if(i == 499)
                    {
                        break;
                    }
                    frmsplash.prbValue = i+1; //ProcessBar的Value
                    System.Threading.Thread.Sleep(100);
                    this.fpSpread1.Sheets[0].Rows[i].BackColor = System.Drawing.Color.Blue;//这里用的是Spread的控件
              }
                }             
            }
      

  4.   

    谢谢,,much0726 
    现在确实不出问题了。非常感谢。能不能给稍微解释下阿。 我上网找了些资料,还是不是很明白
      

  5.   

    使用BeginInvoke异步调用的时候,会让多个线程去访问OrderDepartmentCDOne方法里面的资源(参数,控件等)
    比如说,有两个事务进入OrderDepartmentCDOne方法,要修改如下的参数:
    frmsplash.prbValue = i+1; //ProcessBar的Value
    它们几乎是同时修改的,frmsplash.prbValue是+1还是+2呢?
    如果没有对内存进行保护,在争夺资源的时候就会出错,出错的原因非常多.