正如您在代码的中间看到的,有一个丑陋的线程阻塞代码,它等待文件下载并在命令行中启用进度报告。我的意思是,它还是比Thread.Sleep()
还好,或者正在等待,对不对?无论如何,我知道Wait/Pulse
,但我不知道如何在这里应用。在等待带有进度报告的DownloadFileAsync()的同时暂停主线程
是我的代码的一个完整的重构,以更好地适应单一的异步操作最干净的解决方案?是否可以在WebClient
类中覆盖某些内容以利用Wait/Pulse
类型的等待?
项目,问题中的函数:Github
相关片段:
static void GetPatch(KeyValuePair<string, string> entry, string part)
{
string url = entry.Key,
fname = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1),
path = G.patchPath + "\\" + fname;
bool exists = File.Exists(path);
Console.Write(fname + " ... ");
string message = "local";
if ((exists && GetSHA1(path) != entry.Value) || !exists)
{
if (exists) File.Delete(path);
G.wc.DownloadProgressChanged += Wc_DownloadProgressChanged;
G.wc.DownloadFileAsync(new Uri(url), part);
while (G.wc.IsBusy)
{
// There must be a better way
new System.Threading.ManualResetEvent(false).WaitOne(200);
}
G.wc.DownloadProgressChanged -= Wc_DownloadProgressChanged;
message = "done";
}
if (File.Exists(part)) File.Move(part, path);
G.patchFNames.Enqueue(fname);
Green(message);
}
private static void Wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
int p = e.ProgressPercentage;
p = p < 100 ? p : 99;
Console.Write("{0:00}%\b\b\b", p);
}
请容忍我,这是我的,我已经用C#编写的第一个项目,我绝对OOP和C#的新手。
你绝对需要在代码和清晰度上工作,但总的来说,我认为你是在一个正确的方式。您需要2个异步进程,一个用于文件下载,另一个用于监视进度。第二个进程必须是异步的,这样你才不会阻塞UI,你将不得不使用调度器来更新UI。 – Andrei
你在找什么? https://alexfeinberg.wordpress.com/2014/09/14/how-to-use-net-webclient-synchronously-and-still-receive-progress-updates/ – MistyK
如何转向async \ await?有'DownloadFileTaskAsync'可以等待,这将在这个代码中丢弃大部分的丑陋。 – Evk