Einstellen des Benutzerstatus, wenn asynchron Download
Frage
VS 2008 SP1
Ich bin mit dem Web-clicent einige Dateien asynchron zum Download bereit.
Ich habe 5 Dateien zum Download bereit.
Allerdings mag ich jeden Download überwachen und den Benutzerstatus, wie der Name der Datei gesetzt werden soll, so in der ProgressCompletedEvent kann ich den Benutzerstatus überprüfen, um zu sehen, welche Datei abgeschlossen ist?
Er ist ein kurzer Code-Schnipsel von dem, was ich zu tun versuchen.
// This function will be called for each file that is going to be downloaded.
// is there a way I can set the user state so I know that the download
// has been completed
// for that file, in the DownloadFileCompleted Event?
private void DownloadSingleFile()
{
if (!wb.IsBusy)
{
// Set user state here
wb.DownloadFileAsync(new Uri(downloadUrl), installationPath);
}
}
void wb_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
Console.WriteLine("File userstate: [ " + e.UserState + " ]");
}
void wb_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine("File userstate: [ " + e.UserState + " ]");
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
}
Lösung
Sie können ein beliebiges Objekt übergeben als dritte Argument der DownloadFileAsync () -Aufruf, und Sie werden es wieder als userstate bekommen. In Ihrem Fall können Sie einfach Ihre Dateinamen übergeben.
Andere Tipps
Wie wäre es etwa so:
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);
}
In Ihrem Telefonvorwahl, könnten Sie dann einige Code wie folgt aussehen:
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);
Wenn Sie nichts dagegen nicht darum, es zu wiederverwendbar, kann man eigentlich nur die in Funktionen übergeben Graben alle zusammen und schreiben Sie die Lambda-Ausdrücke direkt in Ihrem Code:
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);
}
zweimal aufgerufen, dies wird Ihnen Ausgang someting wie folgt
/ path / to / file1: 265/265 empfangenen Bytes (100%)
/ Path / to / file1: Abgeschlossen
/ Path / to / file2: 2134/2134 empfangenen Bytes (100%)
/ Path / to / file2: Abgeschlossen