.NET ওয়েবক্লিয়েন্ট অবজেক্টে কীভাবে সময়সীমা পরিবর্তন করা যায়


230

আমি আমার স্থানীয় মেশিনে ক্লায়েন্টের ডেটা ডাউনলোড করার চেষ্টা করছি (প্রোগ্রমেটিকভাবে) এবং তাদের ওয়েবসারভার খুব, খুব ধীর যা আমার WebClientবস্তুর একটি সময়সীমা ঘটাচ্ছে ।

আমার কোডটি এখানে:

WebClient webClient = new WebClient();

webClient.Encoding = Encoding.UTF8;
webClient.DownloadFile(downloadUrl, downloadFile);

এই অবজেক্টে অসীম সময়সীমা সেট করার কোনও উপায় আছে কি? বা যদি না হয় তবে কেউ বিকল্প বিকল্পে আমাকে উদাহরণ দিয়ে সহায়তা করতে পারেন?

ইউআরএল একটি ব্রাউজারে দুর্দান্ত কাজ করে - এটি প্রদর্শিত হতে প্রায় 3 মিনিট সময় নেয়।

উত্তর:


378

আপনি সময়সীমা বাড়িয়ে দিতে পারেন: মূল ওয়েবক্লিয়েন্ট শ্রেণীর উত্তরাধিকারী করুন এবং নীচের উদাহরণের মতো আপনার নিজস্ব টাইমআউট সেট করতে ওয়েবেরিক্যাস্ট গেটরকে ওভাররাইড করুন।

মাই ওয়েবক্লিয়েন্টটি আমার ক্ষেত্রে একটি প্রাইভেট ক্লাস ছিল:

private class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        WebRequest w = base.GetWebRequest(uri);
        w.Timeout = 20 * 60 * 1000;
        return w;
    }
}

5
ডিফল্ট সময়সীমা কি ??
নোকট

23
ডিফল্ট সময়সীমা 100 সেকেন্ড। যদিও এটি 30 সেকেন্ডের জন্য চলবে বলে মনে হচ্ছে।
কার্টার মেডলিন

2
টাইমস্প্যান টাইমস্প্যান.ফ্রমসেকেন্ডস (20) দিয়ে টাইমআউট সেট করা একটু সহজ। মিলিসেকেন্ডস ... দুর্দান্ত সমাধান যদিও!
ওয়েবওয়্যাররা

18
@ ওয়েবেওয়ায়ারস ব্যবহার করা উচিত .TotalMillisecondsএবং না .Milliseconds!
আলেকজান্ডার গালকিন

79
শ্রেণীর নামটি হ'ল: পেন্টেন্ট ওয়েলক্লায়েন্ট;)
জান উইলিম বি

27

প্রথম সমাধানটি আমার পক্ষে কার্যকর হয়নি তবে এখানে এমন কিছু কোড রয়েছে যা আমার পক্ষে কাজ করেছিল।

    private class WebClient : System.Net.WebClient
    {
        public int Timeout { get; set; }

        protected override WebRequest GetWebRequest(Uri uri)
        {
            WebRequest lWebRequest = base.GetWebRequest(uri);
            lWebRequest.Timeout = Timeout;
            ((HttpWebRequest)lWebRequest).ReadWriteTimeout = Timeout;
            return lWebRequest;
        }
    }

    private string GetRequest(string aURL)
    {
        using (var lWebClient = new WebClient())
        {
            lWebClient.Timeout = 600 * 60 * 1000;
            return lWebClient.DownloadString(aURL);
        }
    }

21

আপনি সময় বাড়িয়ে না দিয়ে সময়সীমা সেট করতে না পারার HttpWebRequestপরিবর্তে আপনাকে ব্যবহার WebClientকরতে WebClientহবে (যদিও এটি ব্যবহার করে HttpWebRequest)। HttpWebRequestপরিবর্তে ব্যবহার করা আপনাকে সময়সীমা নির্ধারণ করতে দেয়।


এটি সত্য নয় ... আপনি উপরে দেখতে পাচ্ছেন যে আপনি এখনও ওয়েবক্লিয়েন্ট ব্যবহার করতে পারেন, এমন একটি কাস্টম বাস্তবায়ন যা টাইমআউট নির্ধারণের জন্য ওয়েবরয়েস্টকে ওভাররাইড করে।
ডোমেনিকড্যাটি

7
"System.Net.HttpWebRequest.HttpWebRequest () 'অপ্রচলিত:' এই এপিআই .NET ফ্রেমওয়ার্ক অবকাঠামো সমর্থন করে এবং আপনার কোড থেকে সরাসরি ব্যবহার করার উদ্দেশ্যে নয়"
দরকারীপ্রেমিক

3
@usefulBee - কারণ আপনি যে কন্সট্রাকটর কল না করা উচিত: "Do not use the HttpWebRequest constructor. Use the WebRequest.Create method to initialize new HttpWebRequest objects."থেকে msdn.microsoft.com/en-us/library/... । এছাড়াও স্ট্যাকওভারফ্লো.com
জিজ্ঞাসাগুলি /

কেবল পরিষ্কার করতে: যদিও এই নির্দিষ্ট নির্মাতাকে এড়ানো উচিত (এটি কোনওভাবেই নতুন। নেট সংস্করণগুলির অংশ নয়), এর Timeoutসম্পত্তিটি ব্যবহার করা একেবারে ঠিক HttpWebRequest। এটি মিলিসেকেন্ডে।
মার্সেল

10

নেটওয়ার্ক কেবলটি টেনে আনার সময় ডাব্লু.টাইমআউট কোডটি কাজ করতে পারা যায় নি, এটি ঠিক সময় নিচ্ছে না, এইচটিটিপিওব্রেকয়েস্ট ব্যবহারে সরিয়ে নিয়েছে এবং এখন কাজটি করে।

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(downloadUrl);
request.Timeout = 10000;
request.ReadWriteTimeout = 10000;
var wresp = (HttpWebResponse)request.GetResponse();

using (Stream file = File.OpenWrite(downloadFile))
{
    wresp.GetResponseStream().CopyTo(file);
}

1
এই উত্তরটি দুর্দান্ত কাজ করে, তবে আগ্রহী যে কারও জন্য, যদি আপনি var wresp = await request.GetResponseAsync();পরিবর্তে পরিবর্তে ব্যবহার করেন তবে আপনি wresp = (HttpWebResponse)request.GetResponse();আবার একটি বিশাল সময়সীমা শেষ করতে পারবেন
andrewjboyd

অ্যান্ড্রুজবয়ড: আপনি জানেন যে গেটআরস্পোনসাইক () কেন কাজ করে না?
osexpert

9

সম্পূর্ণতার জন্য, এখানে কিস্পের সমাধানটি ভিবিতে পোর্ট করা হয়েছে (কোনও মন্তব্যে কোড যুক্ত করতে পারে না)

Namespace Utils

''' <summary>
''' Subclass of WebClient to provide access to the timeout property
''' </summary>
Public Class WebClient
    Inherits System.Net.WebClient

    Private _TimeoutMS As Integer = 0

    Public Sub New()
        MyBase.New()
    End Sub
    Public Sub New(ByVal TimeoutMS As Integer)
        MyBase.New()
        _TimeoutMS = TimeoutMS
    End Sub
    ''' <summary>
    ''' Set the web call timeout in Milliseconds
    ''' </summary>
    ''' <value></value>
    Public WriteOnly Property setTimeout() As Integer
        Set(ByVal value As Integer)
            _TimeoutMS = value
        End Set
    End Property


    Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
        Dim w As System.Net.WebRequest = MyBase.GetWebRequest(address)
        If _TimeoutMS <> 0 Then
            w.Timeout = _TimeoutMS
        End If
        Return w
    End Function

End Class

End Namespace

7

যেমন সোহনি বলেছেন, ব্যবহারের পরিবর্তে সম্পত্তিটি ব্যবহার System.Net.HttpWebRequestএবং সেট করুন ।TimeoutSystem.Net.WebClient

তবে আপনি একটি অসীম সময়সীমা মান সেট করতে পারবেন না (এটি সমর্থিত নয় এবং এটি করার চেষ্টা করা একটি নিক্ষেপ করবে ArgumentOutOfRangeException)।

আমি প্রথমে একটি হেড এইচটিটিপি অনুরোধ সম্পাদন করে এবং Content-Lengthআপনি যে ফাইলটি ডাউনলোড করছেন তা ফাইলের বাইট সংখ্যা নির্ধারণ এবং তারপরে GETঅনুরোধের জন্য সেই অনুসারে টাইমআউট মান নির্ধারণ করার জন্য বা কেবলমাত্র একটি দীর্ঘ সময়সীমা মান নির্দিষ্ট করার জন্য সুপারিশ করব অতিক্রম করার আশা কখনই করবেন না


7
'CORRECTED VERSION OF LAST FUNCTION IN VISUAL BASIC BY GLENNG

Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
            Dim w As System.Net.WebRequest = MyBase.GetWebRequest(address)
            If _TimeoutMS <> 0 Then
                w.Timeout = _TimeoutMS
            End If
            Return w  '<<< NOTICE: MyBase.GetWebRequest(address) DOES NOT WORK >>>
        End Function

5

যে সকলের জন্য এসাইক / টাস্ক পদ্ধতির জন্য কাজ করে এমন টাইমআউট সহ ওয়েবক্লিয়েন্টের প্রয়োজন , প্রস্তাবিত সমাধানগুলি কাজ করবে না। এখানে কি কাজ করে:

public class WebClientWithTimeout : WebClient
{
    //10 secs default
    public int Timeout { get; set; } = 10000;

    //for sync requests
    protected override WebRequest GetWebRequest(Uri uri)
    {
        var w = base.GetWebRequest(uri);
        w.Timeout = Timeout; //10 seconds timeout
        return w;
    }

    //the above will not work for async requests :(
    //let's create a workaround by hiding the method
    //and creating our own version of DownloadStringTaskAsync
    public new async Task<string> DownloadStringTaskAsync(Uri address)
    {
        var t = base.DownloadStringTaskAsync(address);
        if(await Task.WhenAny(t, Task.Delay(Timeout)) != t) //time out!
        {
            CancelAsync();
        }
        return await t;
    }
}

আমি এখানে সম্পূর্ণ workaround সম্পর্কে ব্লগ


4

ব্যবহার:

using (var client = new TimeoutWebClient(TimeSpan.FromSeconds(10)))
{
    return await client.DownloadStringTaskAsync(url).ConfigureAwait(false);
}

ক্লাস:

using System;
using System.Net;

namespace Utilities
{
    public class TimeoutWebClient : WebClient
    {
        public TimeSpan Timeout { get; set; }

        public TimeoutWebClient(TimeSpan timeout)
        {
            Timeout = timeout;
        }

        protected override WebRequest GetWebRequest(Uri uri)
        {
            var request = base.GetWebRequest(uri);
            if (request == null)
            {
                return null;
            }

            var timeoutInMilliseconds = (int) Timeout.TotalMilliseconds;

            request.Timeout = timeoutInMilliseconds;
            if (request is HttpWebRequest httpWebRequest)
            {
                httpWebRequest.ReadWriteTimeout = timeoutInMilliseconds;
            }

            return request;
        }
    }
}

তবে আমি আরও আধুনিক সমাধানের প্রস্তাব দিচ্ছি:

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

public static async Task<string> ReadGetRequestDataAsync(Uri uri, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
{
    using var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
    if (timeout != null)
    {
        source.CancelAfter(timeout.Value);
    }

    using var client = new HttpClient();
    using var response = await client.GetAsync(uri, source.Token).ConfigureAwait(false);

    return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}

এটি OperationCanceledExceptionএকটি সময়সীমা পরে নিক্ষেপ করা হবে ।


কাজ হয়নি, অ্যাসিঙ্ক পদ্ধতিটি এখনও অনির্দিষ্টকালের জন্য কাজ করে
অ্যালেক্স

সম্ভবত সমস্যাটি আলাদা এবং আপনার কনফিগারআউট (মিথ্যা) ব্যবহার করা উচিত?
কনস্ট্যান্টিন এস।

-1

কিছু ক্ষেত্রে হেডারগুলিতে ব্যবহারকারী এজেন্ট যুক্ত করা প্রয়োজন:

WebClient myWebClient = new WebClient();
myWebClient.DownloadFile(myStringWebResource, fileName);
myWebClient.Headers["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

এটিই ছিল আমার মামলার সমাধান।

ক্রেডিট:

http://genjurosdojo.blogspot.com/2012/10/the-remote-server-returned-error-504.html

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.