听起来您在询问实现类的最佳实践,该类公开具有类似于 WebClient 的异步版本的方法?
值得注意的是,.NET 框架中通常有两种模式用于支持异步使用的类。例如,您通常会看到像 Stream 这样公开 BeginRead 和 EndRead 的类。这些使用 IAsyncResult 并且使用起来往往更复杂。 (Overview on MSDN)
后来他们提出了event-based async pattern,例如 WebClient 使用的那个,你有一个 DownloadString/DownloadStringAsync 方法和一个相应的 DownloadStringCompleted 事件。对于简单的情况,这更容易使用,但在我看来不如 Begin/End 模式灵活。
因此,在您的示例中,您有两个重载方法。在这种情况下,我将简单地设计它们,使具有较少参数的方法遵循具有更多参数的方法,根据需要传递默认值或空值。您可以有多个 Download/DownloadAsync 重载,但您只能有一个 DownloadCompleted 事件,这很好。
这是一个非常基本的实现。请注意,真正做任何工作的唯一方法是一个同步下载方法。同样重要的是要注意,这也不是最有效的方法。如果你想利用 HttpWebRequest 等的异步 IO 特性,这个例子会很快变得复杂。还有一个我一点都不喜欢的过于复杂的Async Operation 模式。
class Downloader {
public void Download(string url, string localPath) {
if (localPath == null) {
localPath = Environment.CurrentDirectory;
}
// implement blocking download code
}
public void Download(string url) {
Download(url, null);
}
public void DownloadAsync(string url, string localPath) {
ThreadPool.QueueUserWorkItem( state => {
// call the sync version using your favorite
// threading api (threadpool, tasks, delegate.begininvoke, etc)
Download(url, localPath);
// synchronizationcontext lets us raise the event back on
// the UI thread without worrying about winforms vs wpf, etc
SynchronizationContext.Current.Post( OnDownloadCompleted, null );
});
}
public void DownloadAsync(string url) {
DownloadAsync(url, null);
}
private void OnDownloadCompleted(object state) {
var handler = DownloadCompleted;
if (handler != null) {
handler(this, EventArgs.Empty);
}
}
public event EventHandler DownloadCompleted;
}