webClient.DownloadFile()のタイムアウトを設定する


92

webClient.DownloadFile()ファイルのダウンロードに使用していますが、ファイルにアクセスできない場合に時間がかからないように、タイムアウトを設定できますか?

回答:


42

お試しくださいWebClient.DownloadFileAsync()CancelAsync()独自のタイムアウトを使用してタイマーで呼び出すことができます。


2
タイマーやストップウォッチを使いたくない。組み込みのハックまたはAPIアプローチが必要です。タイマー/ストップウォッチをこの機能は多分すでに実装、なぜホイールを再発明している間、私の見ているため、追加のスレッドがかかり使用

@Kilanny:次に、別の答えからのソリューションを使用します。または、HttpClientを使用してTimeoutプロパティを設定します。また、この回答は2009
。– abatishchev

8
.NETで4.5+あなたにも使用することができvar taskDownload = client.DownloadFileTaskAsync(new Uri("http://localhost/folder"),"filename")、その後とtaskDownload.Wait(TimeSpan.FromSeconds(5));
itsho

257

私の答えはここから来ます

基本WebRequestクラスのタイムアウトプロパティを設定する派生クラスを作成できます。

using System;
using System.Net;

public class WebDownload : WebClient
{
    /// <summary>
    /// Time in milliseconds
    /// </summary>
    public int Timeout { get; set; }

    public WebDownload() : this(60000) { }

    public WebDownload(int timeout)
    {
        this.Timeout = timeout;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = base.GetWebRequest(address);
        if (request != null)
        {
            request.Timeout = this.Timeout;
        }
        return request;
    }
}

ベースのWebClientクラスと同じように使用できます。


3
誰かがこの有用なコードに遭遇した場合に備えて、base.GetWebRequest(address)を呼び出す前にタイムアウトを設定する必要がありました
Darthtong

Resharperは、「result」の可能性のあるnull値について不平を言い、Timeout値をWebRequestに設定する前にnullチェックを提案します。逆コンパイルされたコードを見ると、web.configでカスタムWebRequestModulesを提供しない限り不可能に思われますが、そのような賛成された回答のために、念のために追加します。
Kevin Coulombe 2013年

この行でエラーが発生していますrequest.Timeout。エラーmsg 'System.Net.WebRequest' does not contain a definition for 'Timeout' and no extension method 'Timeout' accepting a first argument of type 'System.Net.WebRequest' could be found (are you missing a using directive or an assembly reference?) 、何が欠けていますか?
Eric

1
@Eric:usingこのコードスニペットで使用されるディレクティブを追加しました。
ベニアミン2013

1
@titol:WebClientではなくHttpClientを使用します。
abatishchev 2015

3

これを同期的に行うことを想定して、WebClient.OpenRead(...)メソッドを使用し、それが返すストリームにタイムアウトを設定すると、望ましい結果が得られます。

using (var webClient = new WebClient())
using (var stream = webClient.OpenRead(streamingUri))
{
     if (stream != null)
     {
          stream.ReadTimeout = Timeout.Infinite;
          using (var reader = new StreamReader(stream, Encoding.UTF8, false))
          {
               string line;
               while ((line = reader.ReadLine()) != null)
               {
                    if (line != String.Empty)
                    {
                        Console.WriteLine("Count {0}", count++);
                    }
                    Console.WriteLine(line);
               }
          }
     }
}

WebClientから派生し、GetWebRequest(...)をオーバーライドしてタイムアウトを設定すると、@ Beniaminが提案したように機能しませんでしたが、これは機能しました。


@jeffymorrisはうまくいきませんでした。stream.ReadTimeout実際に要求の実行にかかったよりも大きい値を指定した場合でも、「要求が中止されました-操作がタイムアウトしました」というWebExceptionが引き続き表示されます
chester89

@jeffymorisの場合、webclientサブクラスを使用したソリューションも機能しなかったため、サーバー側の問題である可能性があります
chester89
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.