我有一个简单的代码,我试图更好地理解如何在C#中异步调用方法。
我有一个名为Function1的函数,我想以异步方式运行
sf_open
然后我有第二个功能Function2,我想正常运行(同步)
static void Function1(out int threadId)
{
Console.WriteLine("I'm inside Function 1. Going to sleep for 7 seconds...");
Thread.Sleep(7000);
Console.WriteLine("I'm awake now");
threadId = Thread.CurrentThread.ManagedThreadId;
}
我还创建了一个与Function1
具有相同方法签名的委托static void Function2()
{
Thread.Sleep(3000);
Console.WriteLine("I'm inside Function 2");
}
这是我的主要调用方法:
delegate void AsyncMethodCaller(out int threadId);
在我的main方法中,我希望Function1开始异步运行;然后没有等待它完成,Function2执行。所以我希望得到以下结果:
我在异步函数内部1.进入休眠状态7 秒......我在功能2里面我现在醒了
相反,我得到以下输出:
我在异步函数内部1.进入休眠状态7 秒......我在功能2里面
为什么我的期望与现实不同?为什么“我现在醒来”这条线永远不会到达?
谢谢
答案 0 :(得分:4)
.NET的基本进程生存期规则是当所有前台线程都退出时进程退出。任何后台线程都被简单地中止;这个过程不会等待他们。
此外,当您调用委托的BeginInvoke()
方法时,这会隐式导致使用线程池调用委托。线程池完全由后台线程组成。
换句话说,当你调用BeginInvoke()
时,你告诉.NET使用一个本身不保证自己生命周期的线程来调用委托。一旦进程的单个主前台线程退出,该线程就可以(并且在这种情况下)中止,这在您调用Function2()
之后立即发生。
如果希望异步调用的委托正常完成,则必须明确等待它。 E.g:
IAsyncResult result = caller.BeginInvoke(out threadId, null, null);
Function2();
caller.EndInvoke(out threadId, result);
EndInvoke()
方法将阻塞,直到异步调用的委托完成,允许主线程等待发生,从而确保在调用完成之前不会中止用于调用委托的线程。
您的代码示例的结构表明您已经查看了MSDN的Calling Synchronous Methods Asynchronously,但是如果您还没有我会提到该页面,因为它包含了很多有助于解释如何解释的细节处理这种特殊情况。