我想按顺序下载一个带异步方法的文件 向用户显示下载的实际进度。
using System;
using System.Net;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
public static void downloadFile(string url)
{
Object LockObject = new Object();
using (var client = new WebClient())
{
int left = Console.CursorLeft;
int top = Console.CursorTop;
client.DownloadProgressChanged += (o, e) =>
{
lock (LockObject)
{
Console.SetCursorPosition(0, 0);
Console.Write(e.ProgressPercentage + "%");
}
};
client.DownloadFileAsync(new Uri(url), @"c:\asd");
}
}
static void Main(string[] args)
{
Task task = Task.Factory.StartNew(() => downloadFile("http://download.lsoft.net/ActiveDataStudioSetup.exe"));
task.Wait();
//There can be lots of funcs after download......
//!!!
Console.WriteLine("\nIt should be seen ONLY after the full download");
Console.ReadKey();
}
}
}
下载程序似乎很好,文件正在获取并且我也看到了它的实际状态,但是在调用该方法之后,一切都将在调用之后立即执行,但是主线程应该等待完成下载第一
答案 0 :(得分:2)
问题是您的downloadFile
方法是异步void
方法。该方法只是启动异步操作并立即返回,但它没有提供任何方式通知调用者何时完成。你启动另一个线程中的异步操作,然后等待它在你的main方法中完成启动异步操作,然后再继续没有导致它等待它正在完成下载,正如您所见。
您需要更改下载文件,以便它返回Task
,表明它已完成的时间:
public static Task DownloadFile(string url)
{
using (var client = new WebClient())
{
client.DownloadProgressChanged += (o, e) =>
{
lock (client)
{
Console.SetCursorPosition(0, 0);
Console.Write(e.ProgressPercentage + "%");
}
};
return client.DownloadFileTaskAsync(new Uri(url), @"c:\asd");
}
}
然后当然没有理由从另一个线程启动它。您只需调用该方法即可开始下载:
private static void Main()
{
Task task = DownloadFile("http://download.lsoft.net/ActiveDataStudioSetup.exe");
task.Wait();
Console.WriteLine("\nIt should be seen ONLY after the full download");
Console.WriteLine();
Console.WriteLine("Press any key to Exit. . . ");
Console.ReadKey(true);
}