remoting异步回调的时候,如果是用户误操作,如何在操作完成之前,中断这个异步回调?以下面代码为例,如果点了button1之后,在GetUserInfoCallback完成之前,中断(取消)GetUserInfoCallback的执行.  
        private void button1_Click(object sender, EventArgs e)
        {
            RegisterChannel();
            Rem.User user= (Rem.User)Activator.GetObject(typeof(Rem.User),"tcp://localhost:6666/User");
            bool success;
            string errorString;            Delegate.GetUserInfo getUserInfoDelegate = new Delegate.GetUserInfo(user.GetUserInfo);
           
           AsyncCallback callback=new AsyncCallback(GetUserInfoCallback);          IAsyncResult iar= getUserInfoDelegate.BeginInvoke(txtUserName.Text, txtPassword.Text, out success, out errorString, callback, null);           
            
        }        private void GetUserInfoCallback(IAsyncResult iar)
        {            AsyncResult ar = (AsyncResult)iar;
            Delegate.GetUserInfo getUserInfoDelegate = ar.AsyncDelegate as Delegate.GetUserInfo;            if (iar.IsCompleted)
            {
                bool success;
                string errorString;
                DataSet ds = getUserInfoDelegate.EndInvoke(out success, out errorString, iar);                if (success)
                {
                    SetDataSource(dataGridView1, ds.Tables[0]);
                }
                else
                {
                    SetDataSource(dataGridView1, null);
                    MessageBox.Show(errorString);
                }
            }
            else
            {
                MessageBox.Show("正在进行...");
            }
        }        delegate void SetDataSourceCallback(DataGridView dgv, DataTable dt);        private void SetDataSource(DataGridView dgv, DataTable dt)
        {
            if (dgv.InvokeRequired)
            {
                SetDataSourceCallback d = new SetDataSourceCallback(SetDataSource);
                this.Invoke(d, new object[] {dgv, dt });
            }
            else
            {
                dgv.DataSource= dt;
            }
        }

解决方案 »

  1.   

    你现在的代码是没办法的,因为在你的SetDataSource方法里根本不支持取消的动作.
    你看下BackgroundWorker组件,虽然有提供WorkerSupportsCancellation属性,让你设置你的方法是否支持取消动作,但是那也要你的方法支持取消才可以.也就是你的方法在长时间运算的过程中要检测是否有请求取消的动作,也就是CancellationPending是否被设置成true,才停止运行的.
    也就是你的代码需要在GetUserInfo方法判断一个是否取消的标志,不然是没办法的
      

  2.   

    如果如你所说,那么这个标志位如何传递过来呢?声明一个共享变量,通过用户界面把这个变量值改变,而在GetUserInfo方法中进行判断?
      

  3.   

    如果如你所说,那么这个标志位如何传递过来呢?声明一个共享变量,通过用户界面把这个变量值改变,而在GetUserInfo方法中进行判断?  对!
      

  4.   

    而且GetUserInfo方法中是没有循环的,该在哪个位置判断?
      

  5.   

    GetUserInfo方法里的代码贴出来看看,可能没办法做支持取消的动作
      

  6.   


            public static KidReturnObject  GetPersonInfo(string userName, string password)
            {
                KidReturnObject result = new KidReturnObject();            string sql = string.Format("select * from person where name='{0}'", userName);            // Database db = DatabaseFactory.CreateDatabase("ConnYuJing");
                //DataSet ds = db.ExecuteDataSet(CommandType.Text, sql);            using (SqlConnection conn = new SqlConnection(ConnString.YuJing))
                {
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    SqlDataAdapter da = new SqlDataAdapter(cmd);                DataSet ds = new DataSet();
                    da.Fill(ds);                if (ds.Tables[0].Rows.Count > 0)
                    {
                        if (ds.Tables[0].Rows[0][ColumnName.Person.Password].ToString().Equals(password))
                        {
                            result.ExecuteSuccess= true;
                            result.ReturnObject = ds;
                        }
                        else
                        {
                            result.ExecuteSuccess = false;
                            result.ErrorLevel = ErrorLevel.Low;
                            result.ErrorString= "密码错误!";
                        }
                    }
                    else
                    {
                        result.ExecuteSuccess = false;
                        result.ErrorString="用户不存在!";
                    }                return result ;            }
            }
      

  7.   


    呵呵好几年不搞Remoting,我在csdn上看到这类回复还真是很高兴。
      

  8.   

    调用这个方法public int Fill(System.Data.DataSet dataSet, int startRecord, int maxRecords, string srcTable)不要直接就全部填充,用循环startRecord的方式来填充,在循环中判断是否收到取消的动作。
      

  9.   

    更常用的做法,是让一个长时间执行的东西它经常(同步或者异步)触发事件回调客户,如果客户给设置一个bool值标志是否终端。例如一个进度条,你可以在它的步进时触发的事件中设置一个值它就知道中断了。
      

  10.   

    楼上就是完全的模拟BackgroundWorker所提供的功能,很好。