コードの途中にあるように、ファイルをダウンロードするのを待つ醜いスレッドブロックコードがあり、コマンドラインで進捗レポートを有効にしています。つまり、まだ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つの非同期プロセスが必要です.1つはファイルのダウンロード用で、もう1つは進行状況の監視用です。 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