将一个 APM 操作包装在另一个 APM 操作中

Wrapping an APM operation in another APM operation

我正在使用一些执行异步操作的 APM 方法来实现一个库 I/O。 (为了解决这个问题,我不能使用 Tasks、async/await、Rx、第三方库等)

假设我的一个 APM 库方法 BeginOuter() 只是推迟到另一个 APM 方法 BeginInner() 来执行其异步操作 I/O。有什么理由我不能将 BeginInner() 中的内部 IAsyncResult 重用为 BeginOuter() 中的外部 IAsyncResult,如果我对用户输入所做的其他所有事情都是同步的?如:

// Omitting non-APM parameters for clarity; assume these methods do synchronous work on some other input.

public IAsyncResult BeginOuter(InputStuff stuff, AsyncCallback callback, object state) 
{
    return BeginInner(stuff, result => 
    {
        callback(result);
    }, state);
}

public OutputStuff EndOuter(IAsyncResult result)
{
    EndInner(result);
    // Do some synchronous work to get OutputStuff.
    return MakeOutputStuff();
}

显然,如果 BeginOuter() 将多个异步调用链接在一起以完成其工作,则只将调用方返回等待的第一个调用是错误的。但是如果只有一个异步调用呢?

此外,就我而言,我认为调用者不会在 BeginInner() 完成之后但在他们调用 EndOuter() 之前搞砸——他们将取决于结果 EndOuter() 做任何有用的事情。

只是很难整合现有的所有相关信息。我已经看到了 IAsyncResult 模式的几种实现,但我找不到关于这个特定用例的更多信息,除了:http://mtaulty.com/communityserver/blogs/mike_taultys_blog/archive/2005/02/21/5279.aspx 希望更好地理解其中的微妙之处。

编辑:我确实看到了this question,但我检查时的回复都是"use [library]"、"do it differently"或"implement IAsyncResult"(但没有深入探讨原因)。我试图了解这是否是一件可以接受的事情,或者实施 IAsyncResult 是否是唯一的选择。

在这样的单个操作上搭载一些同步代码会起作用。

如果您添加的代码不阻塞,这可能是最好的,调用者可能不会想到这一点。

不将 state 参数传递给内部操作有点调皮 - 你可能应该从你的 Begin... 方法签名中省略它,或者如果可以的话传递它。