在一个控制台程序里,定义一个委托加入一个方法实例化后,用BeginInvoke进行异步调用,同时增加一个回调方法,回调方法里面用EndInvoke结束异步调用,如下面代码所示。但是执行的时候,程序一闪就完了,加入委托的方法根本不执行。为了能让控制台程序不至于一闪就执行完,我在程序的最后加入readkey,使主程序停在那里,一段时间后检查,增加到委托里面的方法执行了。这个问题很奇怪,难道是需要设置组线程为前台线程,怎么管理主线程与工作线程之间的关系呢? 委托的BeginInvoke 应该是工作线程执行委托里面的方法吧。
(注:增加到委托里面的方法有两个线程,分别向不同的数据库更新数据)private delegate void DelegateDispatchMsg(string DataGroup, string ReferenceId, List<MsgInfo> Msgs, int NumberOfMessages);
DelegateDispatchMsg delegateDispatchMsg = new DelegateDispatchMsg(DispatchMsg);
delegateDispatchMsg.BeginInvoke(DataGroup, ReferenceId, Msgs, NumberOfMessages, new AsyncCallback(CallBackMethod), list);
Console.ReadKey();//为增加主线程的执行时间
private void CallBackMethod(IAsyncResult ar)
{
ArrayList list = (ArrayList)ar.AsyncState;
string DataGroup = (string)list[0];
string ReferenceId = (string)list[1];
List<MsgInfo> Msgs = (List<MsgInfo>)list[2];
int NumberOfMessages = (int)list[3];
DateTime start = (DateTime)list[4];
DelegateDispatchMsg delegateDispatchMsg = (DelegateDispatchMsg)list[5]; delegateDispatchMsg.EndInvoke(ar); if (_IsSuccessful)
Log.DBLog(ReferenceId, DataGroup, NumberOfMessages, start, DateTime.Now, "S");
else
Log.DBLog(ReferenceId, DataGroup, NumberOfMessages, start, DateTime.Now, "F");
}
(注:增加到委托里面的方法有两个线程,分别向不同的数据库更新数据)private delegate void DelegateDispatchMsg(string DataGroup, string ReferenceId, List<MsgInfo> Msgs, int NumberOfMessages);
DelegateDispatchMsg delegateDispatchMsg = new DelegateDispatchMsg(DispatchMsg);
delegateDispatchMsg.BeginInvoke(DataGroup, ReferenceId, Msgs, NumberOfMessages, new AsyncCallback(CallBackMethod), list);
Console.ReadKey();//为增加主线程的执行时间
private void CallBackMethod(IAsyncResult ar)
{
ArrayList list = (ArrayList)ar.AsyncState;
string DataGroup = (string)list[0];
string ReferenceId = (string)list[1];
List<MsgInfo> Msgs = (List<MsgInfo>)list[2];
int NumberOfMessages = (int)list[3];
DateTime start = (DateTime)list[4];
DelegateDispatchMsg delegateDispatchMsg = (DelegateDispatchMsg)list[5]; delegateDispatchMsg.EndInvoke(ar); if (_IsSuccessful)
Log.DBLog(ReferenceId, DataGroup, NumberOfMessages, start, DateTime.Now, "S");
else
Log.DBLog(ReferenceId, DataGroup, NumberOfMessages, start, DateTime.Now, "F");
}
解决方案 »
- 很简单的c#数据库编程,请高手指教!
- VS05 c# 基于桌面treeView怎么传递值?
- C#使用存储过程的问题
- 一个很奇怪的问题
- 程序执行中组织了一段html代码,如何在窗口中显示出来?
- 请问asp.net(c#)如何修改XML中的<![CDATA[]]>数据?
- 求助 c#查询excel,错误:至少一个参数没有被指定值!
- 在c#怎么格式化时间?
- asp.net中的桢结构身份验证问题,100分!
- 关于DataGrid的初学者问题
- 高手请进,求个设计方案
- windows server 2008 x64中安装office2003,dcom中找不到microsoft excel application?
BeginInvoke方法会在线程池里开一个线程来执行,而线程池的线程是后台线程,无法维持进程,所以当主线程结束的时候,后台线程也被迫终止了,当你加了ReadKey之后,由于主线程存在,所以后台线程能正常工作
Thread t;
然后在委托的方法里赋值
t=Thread.CurrentThread;
然后在主线程调用t.Join()方法但是有个小问题,由于是异步的,t.Joint方法很可能比t=Thread.CurrentThread先执行
从来导致null调用
所以可以在t.Join上先调用一下Thread.Sleep(200);
保证t赋值先与t的调用
汗....你完全就没理解......
EndInvoke本来就是等待异步调用结束,如果异步调用没有执行完,EndInvoke会一直挂起,直到其结束
{
Thread thread = null;
AddHandler add = new AddHandler((a, b) =>
{
thread = Thread.CurrentThread;
System.Threading.Thread.Sleep(10000);
return a + b;
});
var ar = add.BeginInvoke(1, 2, iar => { }, add); if (!ar.AsyncWaitHandle.WaitOne(1000, true))
{
thread.Abort();
//ar.AsyncWaitHandle.Close();
textBox1.Text = "timeout!";
}
else
{
textBox1.Text = add.EndInvoke(ar).ToString();
ar.AsyncWaitHandle.Close();
}
}