Масштабирование веб-клиента с использованием threadpool - PullRequest
0 голосов
/ 02 ноября 2011

Мне нужно создать несколько веб-запросов на один и тот же URL-адрес с помощью веб-клиента. Я порождаю поток, используя пул потоков QueueUserWorkItem. Код ниже показывает, как я создаю тему и публикую сообщения с помощью WebClient. Мне пришлось получить класс веб-клиента, чтобы установить свойства Expect100Continue и Timeout.

Когда я запускаю этот код без Thread.Sleep (закомментированная строка в коде потока spawn), я получаю время отклика более 1500 миллисекунд. Пожалуйста, проверьте логику для расчета времени отклика в методе PostToURL. Но если я усыплю 1 секунду перед порождением другого потока, я получу время отклика менее 300 миллисекунд. Я не мог найти причину, почему это так отличается. На самом деле мне нужно довести это время отклика до 300 миллисекунд. Это код теста, который я пишу для тестирования сервиса. Можете ли вы указать, почему разное время отклика?

Вот код, который порождает поток

foreach (var nameValueCollection in requestCollections)
{
    NameValueCollection collection = nameValueCollection;
    ThreadPool.QueueUserWorkItem(a => { if (collection != null) PostToURL    
    (collection); });
    //Thread.Sleep(TimeSpan.FromSeconds(1));
 }

Вот метод, который отправляет на URL

public void PostToURL(NameValueCollection collection)
    {
        DateTime requestStartDate = DateTime.Now;
        DateTime requestEndDate = DateTime.Now;
        string encodedResponse;
        try
        {
            using (var transportType2 = new DerivedWebClient())
            {
                transportType2.Expect100Continue = false;
                transportType2.Timeout = TimeSpan.FromMilliseconds(2000);

                ServicePointManager.ServerCertificateValidationCallback =
                    new RemoteCertificateValidationCallback(delegate { return true; });

                requestStartDate = DateTime.Now;
                var responseArray = transportType2.UploadValues("http://xyz/Post.ashx?AccountName=myaccount",
                                                                "POST", collection);
                requestEndDate = DateTime.Now;
                Console.WriteLine(requestEndDate.Subtract(requestStartDate).TotalMilliseconds);

                encodedResponse = Encoding.ASCII.GetString(responseArray);

                transportType2.Dispose();
            }
        }
        catch (Exception exception)
        {
            requestEndDate = DateTime.Now;
            encodedResponse = exception.ToString();
        }

        //Global variable to record request and response
        responses.Add(new ServiceResponse
        {
            ResponseInMs = (int) requestEndDate.Subtract(requestStartDate).TotalMilliseconds,
            StartTime = requestStartDate,
            EndTime = requestEndDate,
            Response = encodedResponse,
            Request = string.Join(";", collection.Cast<string>()
                        .Select(col => String.Concat(col, "=", collection[col])).ToArray()),
            ApplicationId = collection["ApplicationId"]

        });
    }

ОБНОВЛЕНО Вот код, который выводит веб-клиент

public class DerivedWebClient: WebClient
{
    public bool Expect100Continue
    {
        get;
        set;
    }

    public TimeSpan Timeout
    {
        get;
        set;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = (HttpWebRequest)base.GetWebRequest(address);
        if (request != null)
        {
            request.ServicePoint.Expect100Continue = Expect100Continue;
            request.KeepAlive = false;
            request.Timeout = (int) Timeout.TotalMilliseconds;
        }

        return request;
    }
}

Ответы [ 2 ]

0 голосов
/ 12 января 2012

Этот вопрос может быть повторен до Время загрузки UploadValuesAsync . Но блоки кода разные, я бы рассмотрел разные вопросы, но проблема та же. Ответ на другой вопрос также применим здесь.

0 голосов
/ 19 ноября 2011

HTTP-клиент .NET по умолчанию регулируется на определенное количество одновременных подключений.Я подозреваю, что вы работаете в этом пределе, поэтому каждый поток ждет свободного соединения, прежде чем сделать новый запрос.

Предел по умолчанию будет варьироваться в зависимости от того, используете ли вы клиентское приложение, внутри ASP.net и т. Д., Но вы можете изменить его.Используйте ServicePointManager.DefaultConnectionLimit, чтобы поднять этот предел в глобальном масштабе.

...