Подтвердите, что у Вас есть корректный адрес электронной почты прежде, чем послать электронные письма. Если кто-то дает неверный адрес электронной почты на регистрации, победите их по голове об этом как можно скорее.
Всегда включают ясный, "как отказаться от подписки" информация в КАЖДОМ электронном письме. Не требуйте, чтобы пользователь вошел в систему для отмены подписки, это должен быть уникальный URL для 1 щелчка, отказываются от подписки.
Это будет препятствовать тому, чтобы люди отметили Ваши письма как спам, потому что "отмена подписки" слишком трудна.
Вы можете передать любой объект в качестве третьего аргумента вызова DownloadFileAsync (), и вы получите его обратно как userState. В вашем случае вы можете просто передать свое имя файла.
Как насчет чего-то вроде этого:
private void BeginDownload(
string uriString,
string localFile,
Action<string, DownloadProgressChangedEventArgs> onProgress,
Action<string, AsyncCompletedEventArgs> onComplete)
{
WebClient webClient = new WebClient();
webClient.DownloadProgressChanged +=
(object sender, DownloadProgressChangedEventArgs e) =>
onProgress(localFile, e);
webClient.DownloadFileCompleted +=
(object sender, AsyncCompletedEventArgs e) =>
onComplete(localFile, e);
webClient.DownloadFileAsync(new Uri(uriString), localFile);
}
В вашем вызывающем коде вы могли бы иметь такой код:
Action<string, DownloadProgressChangedEventArgs> onProgress =
(string localFile, DownloadProgressChangedEventArgs e) =>
{
Console.WriteLine("{0}: {1}/{2} bytes received ({3}%)",
localFile, e.BytesReceived,
e.TotalBytesToReceive, e.ProgressPercentage);
};
Action<string, AsyncCompletedEventArgs> onComplete =
(string localFile, AsyncCompletedEventArgs e) =>
{
Console.WriteLine("{0}: {1}", localFile,
e.Error != null ? e.Error.Message : "Completed");
};
downloader.BeginDownload(
@"http://url/to/file",
@"/local/path/to/file",
onProgress, onComplete);
Если вы не против сделать его слишком многоразовым, вы можете на самом деле просто отбросьте все переданные функции и напишите лямбда-выражения прямо в свой код:
private void BeginDownload(string uriString, string localFile)
{
WebClient webClient = new WebClient();
webClient.DownloadProgressChanged +=
(object sender, DownloadProgressChangedEventArgs e) =>
Console.WriteLine("{0}: {1}/{2} bytes received ({3}%)",
localFile, e.BytesReceived,
e.TotalBytesToReceive, e.ProgressPercentage);
webClient.DownloadFileCompleted +=
(object sender, AsyncCompletedEventArgs e) =>
Console.WriteLine("{0}: {1}", localFile,
e.Error != null ? e.Error.Message : "Completed");
webClient.DownloadFileAsync(new Uri(uriString), localFile);
}
Вызывается дважды, это даст вам результат примерно такого рода
/ path / to / file1: 265/265 байтов получено (100 %)
/ путь / к / файлу1: завершено
/ путь / к / файлу2: получено 2134/2134 байта (100%)
/ путь / к / файлу2: завершено