在 AsyncCallback 中使用操作

Use actions inside AsyncCallback

我的 class 执行以下操作(简化):

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 永远不会执行(我使用来自控制台应用程序的 class)。该操作应该向控制台输出一些内容并读取一行,但控制台立即关闭。

我的控制台应用程序:

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- 调用会在某个时间自动关闭。我怎样才能防止这样做?

您正在使用 'Asynchronous Programming Model (APM)' 模式: https://msdn.microsoft.com/en-us/library/ms228963(v=vs.110).aspx

此模型以使用 BeginEnd 方法为代表。

请注意,当调用 Begin 方法(例如您的 BeginEstablish)时,回调方法表示的工作将安排在单独的(后台)线程上进行,并且程序控制在主线程中 returned 立即

假设其他计算可以在主线程上进行,在某个时候回调将在后台线程上完成,然后后台线程的结果将重新加入主线程。

重新加入的机制是调用相应的 End 方法(因此在您的情况下,调用 EndEstablish)。因此,为了防止您的控制台应用程序由于调用 BeginEstablish 的直接 return 控制而退出,您需要执行以下操作:

  • 维护对从 Begin 调用
  • 中 return 编辑的 IAsyncResult 对象的引用
  • 在调用 Begin 之后的代码路径中的某个点,调用相应的 End,传入从调用 Begin 获得的 IAsyncResult 对象
  • 可选地使用第二个参数到 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 的调用将在您的情况下被阻塞。