質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

5806閲覧

巨大なファイルを非同期ダウンロードする処理について

kyosin

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/05/15 06:52

いつもお世話になっております。

現在c# にて8.1ギガのZipファイルをダウンロードしてみようと、以下のソースのような処理を書いて試しています。
現在発生している問題点は、ファイルが5.3ギガバイトを超えた時点で、「WebClientに例外的なエラーが発生しました」と
表示されて、完全なダウンロードが出来ない状態となっています。
4回ほど試しましたが、同じ5.3ギガバイト付近(正確には5381421398、5381319801、5381715394、5381385284)で
ダウンロードが中断されてしまいます。
timeoutが問題かと思い、20分に伸ばしてみましたが、5.3ギガバイトダウンロードした時点で、
それ以上ダウンロードされず、タイムアウトの時間を超えてから「WebClientに例外的なエラーが発生しました」と
メッセージが出るようになっています。

現状のソースコードでどこを変更することにより、8.1ギガのZIPファイルをダウンロードすることが
可能となるでしょうか?
また今利用しているWebClient自体、使用することをお勧めされていないようで
「非同期で、ダウンロードの進捗が目に見える、大容量ファイルのダウンロードも出来る」
の条件を満たした方法があるのでしょうか?

よろしくお願いいたします。

using System; using System.ComponentModel; using System.Windows.Forms; using System.Net; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //ダウンロード中のフラグ private bool onDownloading = false; //ダウンロード用のWebClient private MyWebClient wc = null;     //処理時間計測用 System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); //ダウンロードの進歩イベント private void wc_DownloadProgressChanged(Object sender, DownloadProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; } //完了時のイベント private void wc_DownloadFileCompleted(Object sender, AsyncCompletedEventArgs e) { if ((e.Error != null) && (!e.Cancelled)) { // 計測停止 sw.Stop(); TimeSpan ts = sw.Elapsed; MessageBox.Show("処理時間" + ts.ToString() + "ダウンロード中にエラーが発生しました。内容:" + e.Error.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if (e.Cancelled) { // 計測停止 sw.Stop(); TimeSpan ts = sw.Elapsed; MessageBox.Show("処理時間" + ts.ToString() + "ダウンロードがキャンセルされました。", "完了", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { // 計測停止 sw.Stop(); TimeSpan ts = sw.Elapsed; MessageBox.Show("処理時間" + ts.ToString() + "データのダウンロードが完了しました。", "完了", MessageBoxButtons.OK, MessageBoxIcon.Information); } onDownloading = false; }      //ダウンロードボタンクリック private void button1_Click(object sender, EventArgs e) { // 計測開始 sw.Start(); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //8G.zipファイルをダウンロードする Uri uri = new Uri("8g.zip"); if (wc == null) { wc = new MyWebClient(); //webClientに進行状況、完了時のイベントハンドラを追加 wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); } //ダウンロード開始 wc.DownloadFileAsync(uri, "output.zip"); onDownloading = true; } //キャンセルボタンクリック private void button2_Click(object sender, EventArgs e) { //ダウンロード中なら、ダウンロードをキャンセルする if (onDownloading) { if (wc != null) { wc.CancelAsync(); } } } } //タイムアウト時間を延ばすためクラス作成 public class MyWebClient : System.Net.WebClient { public int Timeout { get; set; } = 120 * 1000; protected override WebRequest GetWebRequest(Uri address) { var w = base.GetWebRequest(address); w.Timeout = Timeout; return w; } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/05/15 06:55

メモリの問題ではないでしょうか。 逐一、使用メモリをチェックしてみては?
m.ts10806

2019/05/15 06:55

回答かどうかというと完全に仮説なので「確認依頼」としてこちらに書きました。
kyosin

2019/05/15 07:17

タスクマネージャー上にあるEXEのメモリの増減を見るで間違いないでしょうか? リリースしたEXEより試しますと起動時は4メガ、実行中は10~11メガと大きくなっていない状態でした。
guest

回答1

0

ベストアンサー

サーバー側とクライアント側のどこに原因があるのかを調べるのは面倒です。どのみちそんな大きなファイルを一度にダウンロードしようというのが間違っているので、小さく分割してダウンロードしてください。そうすれば失敗したところからやり直すことができます。

参考
https://www.atmarkit.co.jp/fdotnet/dotnettips/710resumedown/resumedown.html

投稿2019/05/15 06:55

編集2019/05/15 07:29
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kyosin

2019/05/15 07:56

ご教授いただき、ありがとうございます。 URLを参照しました。 「HttpWebRequestクラスのAddRangeメソッドではダウンロード開始位置だけでなく、開始位置と終了位置を指定することもできる」 小さく分割をする場合、具体的にどのぐらいのサイズまで分割した方がよろしいのでしょうか? (サーバー、クライアント側の問題特定も理解できます。 例えばZuishin様がこの問題を解決するに、まずはどのぐらいの容量分割から試してみるのでしょうか?) (※こちらは疑問に思っている内容です、もしお答えいただけるならお願いいたします。 元々ブラウザ(Vivaldi)から直接、この8.1ギガのZIPファイルのダウンロードが 出来ていた為、同じような考えでデータをダウンロード出来るのではと思っていました。 Visualstudioのインストーラーでも、大容量のデータをダウンロードかつインストールしていたので、 同じような方法でも問題ないのかと思い、このようなプログラムとデータを用意して試していました。 ①サーバー、クライアント側の問題の特定が大変である事 ②大容量のファイルのダウンロードはそう単純にプログラムでは解決しない(難易度が高い) ①②の点から、プログラムとしては安全策を取り、細かくダウンロードするが正解なのでしょうか?)
Zuishin

2019/05/15 08:01

ブラウザからダウンロードできていたのは、おそらくブラウザが自動的に分割ダウンロードしていたからでしょう。 分割する大きさは適当に決めてください。 あまり小さくしすぎるとサーバーの負荷が高くなるので、失敗してもうんざりしない程度の大きさにまとめたらいいと思います。
kyosin

2019/05/15 08:04

わかりました、500メガぐらいの分割で ファイルのダウンロードを試そうと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問