我有一张表格,我从中下载文件。我有一个单独的类(download.cs)来处理文件的下载和进度等。我无法解决如何在文件完成后运行该文件。我可以看到下载后运行的事件,但此时我想恢复调用例程中正在进行的操作。
Form1.cs的
private void btnDownloadProfile_Click(object sender, EventArgs e)
{
tc.SelectTab("tabLog");
Download d = new Download();
d.DownloadFile("http://www.****.com/Downloads/***.zip", appPath + @"Files\***.zip", "Filename");
//At this point i'd like to wait for the download to finish and then execute the download
}
Download.cs
WebClient webClient;
public void DownloadFile(String URL, String Path, String Name)
{
using (webClient = new WebClient())
{
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
Uri Link = new System.Uri(URL);
try
{
Log.addLog("Attempting to download: " + Name);
webClient.DownloadFileAsync(Link, Path);
}
catch (Exception ex)
{
Log.addLog(ex.Message);
}
}
}
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Log.addLog(e.ProgressPercentage.ToString() + "%");
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled == true)
{
Log.addLog("Download has been canceled.");
}
else
{
Log.addLog("Download completed!");
}
}
修改 为了澄清。单击该按钮后,该事件将在Form1.cs上运行,从而启动下载。然后使用Async内容进入后台并自由启动UI。我可以在日志文件中看到发生的下载。一旦Compelted项在Download.cs中运行,我就可以告诉该文件已经完成下载。但是,我在那时似乎无法确定哪个文件已经完成下载,它只是告诉我一个文件已下载。我怎样才能传递给完成文件名,或者在btnDownloadProfile_Click上保留事件,直到文件完成后才能使用它。
答案 0 :(得分:0)
据我所知,你想下载文件,然后继续调用下载方法...如果这是正确的,你可以使用带有async / await的TaskCompletionSource类
(顺便说一句:如果显示下载进度,则可以使用DownloadFileTaskAsync
用法:
async void YourMethod()
{
var dl = new SODownloader();
await dl.DownloadFile(........);
//Do whatever you want to do. Download is finsished....
}
您修改的下载程序类
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
namespace SO3
{
public class SODownloader
{
WebClient webClient;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); //<-----
public Task DownloadFile(String URL, String Path, String Name)
{
using (webClient = new WebClient())
{
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
Uri Link = new System.Uri(URL);
try
{
Debug.WriteLine("Attempting to download: " + Name);
webClient.DownloadFileAsync(Link, Path);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
return tcs.Task; //<-----
}
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Debug.WriteLine(e.ProgressPercentage.ToString() + "%");
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled == true)
{
tcs.TrySetException(new TaskCanceledException("Download has been canceled.")); //<-----
Debug.WriteLine("Download has been canceled.");
}
else
{
tcs.TrySetResult("Download completed!"); //<-----
Debug.WriteLine("Download completed!");
}
}
}
}