我的课程做了以下(简化):
public void Startup(Action myAction)
{
_myAction = myAction;
}
private void EstablishApplicationEndpoint()
{
...
ApplicationEndpoint.BeginEstablish(OnApplicationEndpointEstablishCompleted, null);
}
private void OnApplicationEndpointEstablishCompleted(IAsyncResult result)
{
try
{
...
_myAction();
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
BeginEstablish
方法将AsyncCallback
作为第一个参数。
但是永远不会执行myAction
(我使用控制台应用程序中的类)。该操作应输出一些内容到控制台并读取一行,但控制台立即关闭。
我的控制台应用程序:
static void Main(string[] args)
{
StartPlatform();
}
private static void StartPlatform()
{
...
_platformController.Startup(SendContext);
}
private static void SendContext()
{
Console.WriteLine("Press ENTER to send context");
Console.ReadLine();
...
}
由于控制台无法知道ReadLine
- 呼叫将在某个时间到来,它会自动关闭。我怎么能阻止这样做?
答案 0 :(得分:2)
您正在使用'异步编程模型(APM)模式: https://msdn.microsoft.com/en-us/library/ms228963(v=vs.110).aspx
此模型的典型代表是使用Begin
和End
方法。
请注意,当调用Begin
方法(例如您的BeginEstablish
)时,回调方法表示的工作计划在单独的(后台)线程上进行,并返回程序控制立即在主线程中。
假设是其他计算可以在主线程上发生,在某些时候回调将在后台线程上完成,然后后台线程的结果将重新连接到主线程。
重新加入的机制是调用相应的End
方法(因此在您的情况下,调用EndEstablish
)。因此,为了防止您的控制台应用程序因呼叫从BeginEstablish
立即恢复而退出,您需要执行以下操作:
IAsyncResult
调用返回的Begin
对象的引用Begin
之后的代码路径中的某个位置,调用相应的End
,将通过调用获得的IAsyncResult
对象传递给Begin
Begin
调用以管理状态这看起来像是:
private IAsyncResult EstablishApplicationEndpoint()
{
...
return ApplicationEndpoint.BeginEstablish(OnApplicationEndpointEstablishCompleted, null);
}
...
private static void StartPlatform()
{
...
_platformController.Startup(SendContext);
var asyncResult = _platformController.EstablishApplicationEndpoint();
// Do other things
// Re-join the callback
ApplicationEndpoint.EndEstablish(asyncResult);
}
请记住,如果在调用End
时尚未完成回调,则End
将在此时阻止并等待回调完成。
由于您的回调与控制台互动,我怀疑这意味着您的End
电话会被阻止。