我写了段登陆程序,点击确定后以异步方式调用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("口令错误");
}
}}
但是在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("口令错误");
}
}}
解决方案 »
- 问一个简单的查找
- 请教一个关于wcf异常(System.ServiceModel.ProtocolException)的问题!!!!
- 大家来聊聊C#3.0啊
- 数据库备份
- 我的最后30分--拼了(知道的来救救我)
- 有什么办法能使我,不用Timer控件得情况下,可以在1小时激发一次事件?
- 求一次循环既查找出复行的最优算法! ---------------------- 急
- 如何制作具有zp风格的菜单
- 显示字符串的问题
- 请教关于程序原代码的安全性!!!!!!!!!!!!!!!!!!!!!!!!!!!
- 如何实现动态设置button的borderstyle
- 如何实现将一个链接拖拽到控件上,获得链接的地址?
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("口令错误");
}
}
不过你可以将窗体改成可以异步更新控件的模式。Control.CheckForIllegalCrossThreadCalls = false;这样在你的回调函数里面就可以直接写更新控件的操作了,而不需要用委托的方式了。
我参考一个VS2003写代码,肉眼看和我的完全一样,可我的却不能跑,Essence_zhx(艺森)一贴把我的疑惑全解决了!补充一点,CheckForIllegalCrossThreadCalls 不支持CompactFramework NET 2.0,我正是在这上写的,现在我死心了,不然还得在这点上纠缠耗费时间
感谢感谢