Reputation: 4440
My class does the following (simplified):
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);
}
}
The BeginEstablish
method takes an AsyncCallback
as first parameter.
However myAction
is never executed (I use the class from a console application). The action should output something to the console and read a line, but the console is closed immediately.
My console application:
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();
...
}
As the console can't know that a ReadLine
- call will come at some time it closes automatically. How can I prevent to do so?
Upvotes: 1
Views: 388
Reputation: 4914
You are using the 'Asynchronous Programming Model (APM)' pattern: https://msdn.microsoft.com/en-us/library/ms228963(v=vs.110).aspx
This model is typified by the use of Begin
and End
methods.
Note that when a Begin
method (such as your BeginEstablish
) is invoked, the work denoted by the callback method is scheduled to occur on a separate (background) thread, and program control is returned immediately in the main thread.
The assumption is that other computation can occur on the main thread, at some point the callback will have completed on the background thread, and the results of the background thread will then be re-joined to the main thread.
The mechanism for re-joining is a call to a corresponding End
method (so in your case, a call to EndEstablish
). As such, to prevent your console application from exiting due to the immediate return of control from the call to BeginEstablish
, you need to do the following:
IAsyncResult
object that is returned from the Begin
callBegin
, call the corresponding End
, passing in the IAsyncResult
object obtained from the call to Begin
Begin
call to manage stateWhat this might look like is:
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);
}
Keep in mind that if the callback has not yet completed by the time End
is called, End
will at that point block and wait for the callback to complete.
Since your callback is interacting with the Console, I suspect this will mean the call to End
will be blocking in your case.
Upvotes: 2