Action<T>与标准返回的区别

6

我不是C#专家,更多的是Objective-C方面的知识,但最近我看到了很多这样的实现:

public void Method(Action<ReturnType> callback, params...)

替代方案:

public ReturnType Method(params...)

这里有一个例子是MVVM Light Framework,开发人员使用第一种方法实现数据服务合同(和实现)。那么我的问题是:为什么这样做?只是个人喜好问题还是第一种方法默认是异步的(给定函数指针)?如果是这样,标准返回是否已经死亡?我问这个问题是因为我个人更喜欢第二种方法,当我看到API时更清晰明了。

如果你还没有遇到过它,使用任务并行库时,提供异步方法的库通常会提供Task<ReturnType> Method(params...)而不是采用回调函数,但对于需要与不支持Task<T>的框架一起工作的库来说,这可能不是一个选项(例如,Silverlight在版本5中添加了Task<T>,因此任何Silverlight 4或之前的内容都需要使用回调函数或其他模式)。 - James Manning
@JamesManning 我看到了一些看起来非常清晰的TPL实现。它们在“幕后”是一样的吗? - Erre Efe
我认为这取决于实现库是什么。从概念上讲,TPL(任务并行库)更好一些(在我看来),因为它处理取消和异常等问题。通过使用新的语言特性,您还可以使用await关键字编写感觉像同步代码的内容,这使您避免编写回调方法,让编译器为您重写该方法。 - James Manning
2个回答

10
与返回ReturnType的API不同,带有回调函数的版本可以立即返回并稍后执行回调。当返回值不会立即可用,获取它需要相当长的时间时,这可能非常重要。例如,从Web服务请求数据的API可能需要相当长的时间。当结果数据不是必需的时候,您可以发起一个调用,并提供异步回调。这样调用者就可以立即继续进行,并在通知可用时处理通知。
考虑一个API,它接收一个图像的URL,并返回内存中图像的表示。如果您的API是
Image GetImage(URL url)

如果您的用户需要拉取十张图片,则他们需要在请求下一张图片之前等待每张图片完成加载,或者显式地开启多个线程。

另一方面,如果您的API是

void Method(Action<Image> callback, URL url)

那么你的API的用户将同时启动全部十个请求,并在这些图像异步变为可用时显示它们。采用这种方法可以极大地简化用户所需进行的线程编程。


你知道Java中有没有相应的东西吗? - dantuch
2
Java 没有委托,因此没有直接等效项。但是,您可以使用一个接口来实现类似的功能,并使用匿名类来实现它。 - svick

3
第一种方法很可能是异步方法,该方法立即返回,并且在操作完成后调用回调函数。
第二种方法是在C#中同步方法的标准返回方式。
当然,API设计人员可以自由地选择他们认为适合的任何签名;并且可能有其他潜在的细节来证明回调风格的正当性。但是,作为一个经验法则,如果您看到回调风格,请期望该方法是异步的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接