0

コードが長時間待機するという問題があります HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 。何が間違っていますか? キューから悪いプロキシを取得することがあるので、タイムアウトしてスキップできるようにしたいと考えています。

        Boolean match = false;
        String clean = String.Empty;
        String msbuff;
        IWebProxy insideProxy;
        try
        {
            //grab proxies based on queue
            String proxyQueItem = Proxy_Que(_rankingConnectionString);
            insideProxy = new WebProxy(proxyQueItem);

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(ResultURL);
            request.Proxy = insideProxy;
            request.Timeout = 15*1000;

            using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream streamResponse = response.GetResponseStream();
                    StreamReader streamRead = new StreamReader(streamResponse);
                    msbuff = streamRead.ReadToEnd();
                    //get rid of , -, (, )
                    msbuff = msbuff.Replace(" ", String.Empty).Replace(" ", String.Empty);
                    msbuff = msbuff.Replace("-", String.Empty);
                    msbuff = msbuff.Replace("(", String.Empty);
                    msbuff = msbuff.Replace(")", String.Empty);
                    //attempt to find phone number
                    match = msbuff.Contains(Listing.PhoneNumber);
                    streamRead.Close();
                }

            }
        }
        catch (Exception lk)
        { }
4

4 に答える 4

2

この同じ問題に遭遇しました。問題はタイムアウト コードにあります。あなたが持っている:

request.Timeout = 15*1000;

必要なもの:

request.Timeout = 15*1000;
request.ReadWriteTimeout = 15*1000;

.Timeout 属性は、送信時のタイムアウト用です。ただし、リクエストが送信されて読み取りが開始されると、リクエストの全体的なタイムアウトが発生します。ReadWriteTimeout 属性を介して設定されます。

ReadWriteTimeout のデフォルト値は 5 分です。これが、実際の動作が見られる理由です。

于 2013-08-21T12:11:52.333 に答える
1

以前に問題に遭遇しましたが、タイムアウト設定を簡単に変更するだけで修正されました。これは C# ではなく VB.NET ですが、理解できるはずです。まず、スレッド化できる 2 番目のタイムアウト メソッドを指定します。

Private Sub TimeoutCallback(ByVal state As Object, ByVal timedOut As Boolean)
        If timedOut Then
            Dim request As Net.HttpWebRequest = state
            If Not (request Is Nothing) Then
                request.Abort()
            End If
        End If
    End Sub

次に、リクエストを作成して読み返すと、次のように設定できます。

Try
            Dim myHttpWebRequest1 As Net.HttpWebRequest
            ' Create a new HttpWebrequest object to the desired URL.
            myHttpWebRequest1 = CType(WebRequest.Create(String.Format("http://{0}:{1}", inURL, inPORT)), Net.HttpWebRequest)

            ' Create an instance of the RequestState and assign the previous myHttpWebRequest1
            ' object to it's request field.  
            Dim myRequestState As New RequestState()
            myRequestState.request = myHttpWebRequest1
            ' Start the Asynchronous request.
            allDone.Reset()
            Dim result As IAsyncResult = CType(myHttpWebRequest1.BeginGetResponse(AddressOf RespCallback, myRequestState),  _
                                               IAsyncResult)
            ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, _
                                                   New WaitOrTimerCallback(AddressOf TimeoutCallback), _
                                                   myHttpWebRequest1, DefaultTimeout, True)
            allDone.WaitOne()

TheadPool 行 (下から 2 番目) に注意してください。これは別のスレッドでタイムアウト メソッドを送信するため、無効な IP アドレスまたはホストが原因で他の要求がハングアップした場合でも、要求をキャンセルできます。

于 2012-06-26T16:02:48.677 に答える
1

15 秒のタイムアウトを指定しているため、その 15 秒よりも長く待機していると想定しています。コードの遅延の理由は、接続が利用可能になるのを待っていることが原因である可能性があります。接続の待機に費やされる時間は、リクエストのタイムアウトとは無関係です。

デフォルトでは、.NET は「エンドポイント」(IP アドレス) への同時接続を 2 つだけ許可していると思います。これは、アプリ/Web 構成を介して構成できます。

<system.net>
  <connectionManagement>
    <add address="www.example.com" maxconnection="10"/>
  </connectionManagement>
</system.net>

ただし、これでは問題が解決しない場合があります。これは、通信しているサーバーがクライアントごとに限られた数の接続しか許可しない場合があるためです。あなたの代理人も関与している可能性があります。

于 2012-05-02T21:20:46.640 に答える
0

プロキシのキューがあり、タイムアウトして次のプロキシにスキップする必要がある場合は、応答が返されるまでループして、エラーをキャッチし、毎回キューから新しいプロキシを取得します。このようなもの ...

private string requestByProxy(string url)
{
    string responseString, proxyAddress;

    while (responseString == null)
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            // set properties, headers, etc

            proxyAddress = getNextProxy();

            if (proxyAddress == null)
                throw new Exception("No more proxies");

            request.Proxy = new WebProxy(proxyAddress);
            request.Timeout = 15 * 1000;

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());
            responseString = sr.ReadToEnd();
        }
        catch (WebException wex)
        {
            continue;
        }
    }

    return responseString;
}
于 2012-05-03T00:58:06.693 に答える