Setel waktu tunggu untuk webClient.DownloadFile ()

92

Saya menggunakan webClient.DownloadFile()untuk mengunduh file, dapatkah saya menyetel waktu tunggu untuk ini sehingga tidak akan memakan waktu lama jika tidak dapat mengakses file?

UnkwnTech
sumber

Jawaban:

42

Coba WebClient.DownloadFileAsync(). Anda dapat menelepon CancelAsync()dengan timer dengan batas waktu Anda sendiri.

abatishchev
sumber
2
Saya tidak ingin menggunakan timer atau stopwatch. Saya ingin pendekatan hack atau api bawaan. Menggunakan pengatur waktu / stopwatch membutuhkan thread tambahan untuk menonton, sementara fitur ini mungkin sudah diterapkan, jadi mengapa menciptakan kembali roda
@Kilanny: lanjutkan dengan solusi dari jawaban lain. Atau gunakan HttpClient dan setel properti Timeout. Juga harap dicatat bahwa jawaban ini dari 2009.
abatishchev
8
di .Net 4.5+ Anda juga dapat menggunakan var taskDownload = client.DownloadFileTaskAsync(new Uri("http://localhost/folder"),"filename")dan kemudiantaskDownload.Wait(TimeSpan.FromSeconds(5));
itsho
257

Jawaban saya datang dari sini

Anda dapat membuat kelas turunan, yang akan menyetel properti batas waktu dari WebRequestkelas dasar :

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;
    }
}

dan Anda dapat menggunakannya seperti kelas WebClient dasar.

Beniamin
sumber
3
Seandainya orang lain menemukan kode bermanfaat ini, saya harus menyetel batas waktu sebelum memanggil base.GetWebRequest (alamat)
Darthtong
Resharper mengeluh tentang kemungkinan nilai null untuk "result" dan menyarankan pemeriksaan null sebelum menyetel nilai Timeout ke WebRequest. Melihat kode yang didekompilasi, tampaknya tidak mungkin kecuali Anda memberikan WebRequestModules kustom di web.config Anda, tetapi untuk jawaban yang diberi suara tinggi, saya akan menambahkannya untuk berjaga-jaga.
Kevin Coulombe
Saya mendapatkan kesalahan di baris ini request.Timeout. Pesan kesalahan '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?) , apa yang saya lewatkan?
Eric
1
@Eric: Saya telah menambahkan usingarahan yang digunakan oleh cuplikan kode ini.
Beniamin
1
@titol: gunakan HttpClient daripada WebClient.
abatishchev
3

Dengan asumsi Anda ingin melakukan ini secara sinkron, menggunakan metode WebClient.OpenRead (...) dan menyetel waktu tunggu pada Stream yang dikembalikannya akan memberi Anda hasil yang diinginkan:

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);
               }
          }
     }
}

Berasal dari WebClient dan mengganti GetWebRequest (...) untuk menyetel batas waktu yang disarankan @Beniamin, tidak berfungsi untuk saya seperti, tetapi ini berhasil.

jeffrymorris
sumber
@ jeffymorris tidak bekerja untuk saya. Saya masih mendapatkan WebException yang mengatakan "permintaan dibatalkan - waktu operasi telah habis" bahkan jika saya menentukan stream.ReadTimeoutlebih besar dari yang sebenarnya diperlukan untuk menjalankan permintaan
chester89
@jeffymoris di sisi lain, solusi dengan subkelas webclient juga tidak berfungsi, jadi mungkin ada masalah di sisi server
chester89