以下的代码是框架上的一个控件,实现目的是异步调用方法刷新控件 。
这段类似的代码在主窗口上运行没问题。而在控件上则等不到异步调用的完成。望高手指点哦~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服务,刷新框架的控件
}
这段类似的代码在主窗口上运行没问题。而在控件上则等不到异步调用的完成。望高手指点哦~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服务,刷新框架的控件
}
//异步开始
//如果参数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);
}
我使用这个的使用会产生错误, 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); ///这里出错,"指定的转换无效。"},不知为何 ???
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);
}
}
IAsyncResult ar = wb.BeginInvoke(FressMsg, null);//wb 是你的控件名字.FressMsg.EndInvoke(ar);
改为
wb.EndInvoke(ar);试试.
办法就是 tmrGetMsg_Tick()里面对控件操作的方法也使用委托加invoke。
8楼说的方法 我再试试看
试了不行~ 还是要用到控件的时候用委托invoke。