异步调用同步方法

时间:2016-04-28 23:57:40

标签: c# multithreading asynchronous

我有一个简单的代码,我试图更好地理解如何在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里面

为什么我的期望与现实不同?为什么“我现在醒来”这条线永远不会到达?

谢谢

1 个答案:

答案 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,但是如果您还没有我会提到该页面,因为它包含了很多有助于解释如何解释的细节处理这种特殊情况。