我写了段登陆程序,点击确定后以异步方式调用webserver的登陆函数,同时把登陆菜单上的text改为“正在登陆”,在回调函数LoginCallback里写如果验证通过的话就关闭登陆窗口,如果失败的话就把登陆菜单上的文字改回“登陆”。
  但是在LoginCallback里直接更新菜单文字会蹦出异常说和控件不在一个线程里,于是我得在建个函数LoginCallback2和与它对应的委托AsnycLoginCallback2,在LoginCallback2里访问菜单上的问题,然后在LoginCallback里用窗口的Invoke来调用这AsnycLoginCallback2,才可。简直麻烦死了。是不是我不会用委托啊,我把这页代码贴出来,大家伙帮看看那!public partial class FormLogin : Form
{
private void mnuConfirm_Click(object sender, EventArgs e)
{
mnuConfirm.Text = "正在登录...";
//webService.是web serverice代理对象
asyncResultLogin = webService.BeginLogin("xxx", "yyy", LoginCallback, null);
}//登录回调函数
private void LoginCallback(System.IAsyncResult asyncResult)
{
//调用Web Services的登陆函数取得验证结果
bool ret = webService.EndLogin(asyncResult);
//通过委托去更新菜单饿、文字。(在这里如果访问窗口上的话会提示不在一个线程云云
AsyncLoginCallback2 asyncLoginCallback2 = new AsyncLoginCallback2(LoginCallback2);
this.Invoke(asyncLoginCallback2, new object[] { ret });
}
public delegate void AsyncLoginCallback2(bool ret);//这函数负责更新菜单界面,通过上面的AsyncLoginCallback2间接的被调用
private void LoginCallback2(bool ret)
{
if (ret)
//关闭窗口
this.DialogResult = DialogResult.OK;
else
{
//更新菜单文字
mnuConfirm.Text = "登录";
MessageBox.Show("口令错误");
}
}}

解决方案 »

  1.   

    //登录回调函数
    private void LoginCallback(System.IAsyncResult asyncResult)
    {
    //调用Web Services的登陆函数取得验证结果
    bool ret = webService.EndLogin(asyncResult);
    //通过委托去更新菜单饿、文字。(在这里如果访问窗口上的话会提示不在一个线程云云
    AsyncLoginCallback2 asyncLoginCallback2 = new AsyncLoginCallback2(LoginCallback2);
    LoginCallback2(ret);
    }
    public delegate void AsyncLoginCallback2(bool ret);//这函数负责更新菜单界面,通过上面的AsyncLoginCallback2间接的被调用
    private void LoginCallback2(bool ret)
    {
    if (InvokeRequired)
    {
       Invoke(new AsyncLoginCallback2(LoginCallback2), ret);
    return;
    }
    if (ret)
    //关闭窗口
    this.DialogResult = DialogResult.OK;
    else
    {
    //更新菜单文字
    mnuConfirm.Text = "登录";
    MessageBox.Show("口令错误");
    }
    }
      

  2.   

    楼上兄弟的修改跟原来那个是换汤不换药没啥大意思啊,在回调函数里还是得去调用个函数,只不过在那函数里再Invoke一下自己的委托。是不是也只能就这样没了、没可以简化的了?
      

  3.   

    在.Net 1.1种窗体控件是可以异步更新的,但是在2.0之后默认情况下是不允许异步更新的。
    不过你可以将窗体改成可以异步更新控件的模式。Control.CheckForIllegalCrossThreadCalls = false;这样在你的回调函数里面就可以直接写更新控件的操作了,而不需要用委托的方式了。
      

  4.   

    对Essence_zhx(艺森) 感激涕零啊!
    我参考一个VS2003写代码,肉眼看和我的完全一样,可我的却不能跑,Essence_zhx(艺森)一贴把我的疑惑全解决了!补充一点,CheckForIllegalCrossThreadCalls 不支持CompactFramework NET 2.0,我正是在这上写的,现在我死心了,不然还得在这点上纠缠耗费时间
    感谢感谢