Похоже, вы спрашиваете о передовых методах реализации класса, который предоставляет методы, которые имеют асинхронные версии, аналогичные тем, что делает WebClient?
Стоит отметить, что в .NET Framework обычно используются два шаблона для классов, поддерживающих асинхронное использование. Например, вы обычно видите классы, такие как Stream, которые предоставляют BeginRead и EndRead. Они используют IAsyncResult и, как правило, более сложны в использовании. ( Обзор на MSDN )
Позже они придумали основанный на событиях асинхронный шаблон , такой как тот, который используется WebClient, где у вас есть метод DownloadString / DownloadStringAsync и соответствующее событие DownloadStringCompleted. С этим проще работать в простых случаях, но, на мой взгляд, он не такой гибкий, как шаблон «Начало / Конец».
Итак, в вашем примере у вас есть два перегруженных метода. В этом случае я просто разработал бы их так, чтобы метод с меньшим количеством параметров относился к методу с большим количеством параметров, передавая значения по умолчанию или нули при необходимости. У вас может быть несколько перегрузок Download / DownloadAsync, но у вас может быть только одно событие DownloadCompleted, и это нормально.
Вот очень простая реализация. Обратите внимание, что единственный метод, который действительно выполняет какую-либо работу, - это один синхронный метод Download. Также важно отметить, что это также не самый эффективный способ сделать это. Если вы хотите воспользоваться возможностями асинхронного ввода-вывода HttpWebRequest и тому подобным, этот пример быстро усложнится. Существует также слишком сложный шаблон 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;
}