Загрузка асинхронного файла с помощью панели выполнения

Я пытаюсь изменить ход выполнения WebClient прогресса, поскольку прогресс загрузки WebClient изменяется. Этот код все еще загружает файл, но когда я вызываю startDownload() окно зависает при загрузке файла. Я хотел бы, чтобы пользователь мог видеть изменение хода работы при загрузке заставки. Есть ли способ исправить это, чтобы пользователь мог увидеть прогресс progressBar2 ?

 private void startDownload() { WebClient client = new WebClient(); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); client.DownloadFileAsync(new Uri("http://joshua-ferrara.com/luahelper/lua.syn"), @"C:\LUAHelper\Syntax Files\lua.syn"); } void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { double bytesIn = double.Parse(e.BytesReceived.ToString()); double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); double percentage = bytesIn / totalBytes * 100; label2.Text = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive; progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); } void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { label2.Text = "Completed"; } 

Вы должны вызвать startDownload() из streamа пользовательского интерфейса. Вся идея WebClient.DownloadFileAsync() заключается в том, что она автоматически создаст рабочий stream, не блокируя вызывающий stream. В startDownload() вы указали обратные вызовы, которые изменяют элементы управления, которые, как я полагаю, были созданы streamом пользовательского интерфейса. Таким образом, если вы вызываете startDownload() из фонового streamа, это вызовет проблемы, потому что stream может изменять только созданные элементы пользовательского интерфейса.

Способ, которым он должен работать, – это вызвать startDownload() из streamа пользовательского интерфейса, startDownload() поскольку вы определили, что он устанавливает обратные вызовы вызовов, которые обрабатываются streamом пользовательского интерфейса. Затем он запускается асинхронно и возвращается немедленно. Поток пользовательского интерфейса будет уведомлен о том, когда изменения будут выполнены, и код, отвечающий за обновление элемента управления выполнением, будет выполняться в streamе пользовательского интерфейса, и проблем не должно быть.

Пользовательский интерфейс будет заморожен, когда вы нажмете startDownload () . Если вы не хотите, чтобы форма формы зависала, вы используете startDownload () в другом streamе и обновляете прогресс в кросс-threaded. В одну сторону,

 private void startDownload() { Thread thread = new Thread(() => { WebClient client = new WebClient(); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); client.DownloadFileAsync(new Uri("http://joshua-ferrara.com/luahelper/lua.syn"), @"C:\LUAHelper\Syntax Files\lua.syn"); }); thread.Start(); } void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { this.BeginInvoke((MethodInvoker) delegate { double bytesIn = double.Parse(e.BytesReceived.ToString()); double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); double percentage = bytesIn / totalBytes * 100; label2.Text = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive; progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); }); } void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { this.BeginInvoke((MethodInvoker) delegate { label2.Text = "Completed"; }); } 

Подробнее читайте multithreading в Google, например http://msdn.microsoft.com/en-us/library/ms951089.aspx

– Исправлена ​​ошибка закрытия); к объявлению bgThread

Я считаю, что эта статья приведет вас в правильном направлении http://www.dreamincode.net/forums/topic/115491-download-file-asynchronously-with-progressbar/ .

И в этой статье MSDN http://msdn.microsoft.com/en-us/library/ms229675.aspx обсуждается, как «Файл загружается в рабочий stream компонента BackgroundWorker, который запускает обработчик событий DoWork. Этот stream начинается, когда ваш код вызывает метод RunWorkerAsync ».

  public class ProgressEventArgsEx { public int Percentage { get; set; } public string Text { get; set; } } public async static Task DownloadStraingAsyncronous(string url, IProgress progress) { WebClient c = new WebClient(); byte[] buffer = new byte[1024]; var bytes = 0; var all = String.Empty; using (var stream = await c.OpenReadTaskAsync(url)) { int total = -1; Int32.TryParse(c.ResponseHeaders[HttpRequestHeader.ContentLength], out total); for (; ; ) { int len = await stream.ReadAsync(buffer, 0, buffer.Length); if (len == 0) break; string text = c.Encoding.GetString(buffer, 0, len); bytes += len; all += text; if (progress != null) { var args = new ProgressEventArgsEx(); args.Percentage = (total <= 0 ? 0 : (100 * bytes) / total); progress.Report(args); } } } return all; } // Sample private async void Bttn_Click(object sender, RoutedEventArgs e) { //construct Progress, passing ReportProgress as the Action var progressIndicator = new Progress(ReportProgress); await TaskLoader.DownloadStraingAsyncronous(tbx.Text, progressIndicator); } private void ReportProgress(ProgressEventArgsEx args) { this.statusText.Text = args.Text + " " + args.Percentage; } 
Давайте будем гением компьютера.