【问题标题】:Wrapping an APM operation in another APM operation在另一个 APM 操作中包装一个 APM 操作
【发布时间】:2015-05-01 21:29:16
【问题描述】:

我正在使用一些执行异步 I/O 的 APM 方法来实现一个库。 (为了不碍事,我不能使用 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,但我检查时的响应都是“使用[库]”、“以不同的方式做”或“实现 IAsyncResult”(但没有进入为什么)。我试图了解这是否可以接受,或者实现 IAsyncResult 是否是城里唯一的游戏。

【问题讨论】:

    标签: .net asynchronous iasyncresult


    【解决方案1】:

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

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

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

    【讨论】:

    • 糟糕,我确实忘记在我的伪代码中传递 state 参数。修好了,谢谢。当您说“如果我添加的代码没有阻塞”时-您在这里指的是仅长时间运行的阻塞操作吗?假设 MakeOutputStuff() 运行得非常快,并且没有进行任何额外的 I/O 等操作。
    • 是的,我只是想避免“应该”异步的事情。
    猜你喜欢
    • 2017-07-04
    • 2021-03-14
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    相关资源
    最近更新 更多