我实现了一个带有一些执行异步I / O的APM方法的库。 (为了解决这个问题,我不能使用Tasks,async / await,Rx,第三方库等。)
假设我的一个APM库方法BeginOuter()
只是推迟到另一个APM方法BeginInner()
来执行其异步I / O.是否有任何理由我无法将IAsyncResult
内部的BeginInner()
重新用作IAsyncResult
中的BeginOuter()
,如果其他所有我正在使用// 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()
之前就会陷入困境 - 他们会去取决于 DtsEventHandler ehOnError = (DtsEventHandler)package.EventHandlers.Add("OnError");
Executable execOnError = ehOnError.Executables.Add("STOCK:SQLTask");
TaskHost thOnError = (TaskHost)execOnError;
thOnError.Name = "sql_Exec_LogMessage_Error";
thOnError.SetExpression("SqlStatementSource", "@[User::sql_LogMessageError]");
thOnError.Properties["Connection"].SetValue(thOnError, cmag.ID);
// Parameter mapping?
的结果来做任何有用的事情。
只是很难将所有相关信息整合到那里。我已经看到了IAsyncResult模式的几个实现,但除了以下内容之外,我无法找到关于这个特定用例的更多信息:http://mtaulty.com/communityserver/blogs/mike_taultys_blog/archive/2005/02/21/5279.aspx我们希望能够更好地理解这些细微之处。
修改:我确实看到了this question,但我检查时的回复都是"使用[库]","做到了不同的",或者"实现IAsyncResult" (但没有进入原因)。我试图了解这是否是可接受的事情,或者实施IAsyncResult是镇上唯一的游戏。
答案 0 :(得分:1)
在单个操作上捎带一些同步代码就好了。
如果您添加的代码没有阻止,调用者可能不会预期,这可能是最好的。
不将state
参数传递给内部操作有点顽皮 - 您应该从Begin...
方法签名中省略它,或者如果可以的话将其传递给它。