我是异步编程的新手,我正在阅读一本展示以下 API 示例的书:
// synchronous version
SearchResults GetResults(int page, int pageSize, out int itemsReturned);
// asynchronous version
IAsyncResult BeginGetResults(int page,
int pageSize,
out int itemsReturned,
AsyncCallback callback,
object state);
SearchResults EndGetResults(out int itemsReturned, IAsyncResult iar);
请注意,Begin 方法采用“out”参数作为 out int itemsReturned
以下是作者的解释:
事实证明这是抽象泄漏。 CLR 没有输出参数的概念;它是 C# 语言的习惯用法。在 CLR 级别,out 参数只是 ref 参数,C# 编译器 强制执行特定的使用模式。因为异步编程模型不是特定于语言的特性,所以它必须符合 CLR 的需要。现在 ref 参数既可以是输入也可以是输出;因此,CLR 不知道这些 out 参数仅用于输出,因此必须将它们放在 Begin 方法和 End 方法上。
我还是很困惑,下面是我的问题:
Q1- 我们知道 out
参数需要在方法返回前赋值,那么在这种情况下,itemsReturned
是否在 Begin 方法结束后设置为 0?设置某物有什么意义,你知道它在当前阶段是不正确的?
Q2-在 Begin 方法中去掉 out int itemsReturned
是不是更直接:
IAsyncResult BeginGetResults(int page,
int pageSize,
AsyncCallback callback,
object state);
我们仍然可以在 End 方法中使用 out int itemsReturned
?
最佳答案
Q1。我同意;这似乎是作者的一个糟糕的设计想法,而且无论如何都不典型;我怀疑作者没有很好地理解公认的令人困惑的模式,只是简单地黑掉了一些东西;也许他们已经在非异步方法上有了 out
API,并希望它保持一致?
Q2。是的,但我会更进一步,将返回的项目作为 SearchResults
的附加属性,而不是 的
out
参数>EndGetResults
但强调:这不是执行异步代码的当前/首选方式;如果你刚开始,不要走这条路;我只想:
SearchResults Search(int page, int pageSize);
async ValueTask<SearchResults> SearchAsync(int page, int pageSize);
并且在 SearchResults
上有 public int ItemsReturned {get;}
。
关于c# - begin方法为什么要带参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57907934/