powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить данные с потоков
12 сообщений из 12, страница 1 из 1
Получить данные с потоков
    #39121501
IPmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. У меня такая задача. на сервере отправить разом 100 запросов и рассчитать среднее время ответа. Пробую так
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
     public static List<long> result = new List<long>();
       static  void Main(string[] args)
       {


           var r = 0;;
            for (int i = 1; i <= 100; i++)
            {
                Console.WriteLine("Send request " + (i));
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                WebClient cli = new WebClient();
    Task.Factory.StartNew(() =>
                {
                    cli.DownloadStringCompleted += (sender, e) =>
                    {
                        stopwatch.Stop();
                        var elapsed_time = stopwatch.ElapsedMilliseconds;
                        Console.WriteLine("Get result request " + (result.Count + 1) + " mlsc = " + elapsed_time);

                        result.Add(elapsed_time);
                     stopwatch.Reset();
                        r++;
                    };
                    cli.DownloadStringAsync(new Uri("http://www.weather.gov"));
                });
 
 
 
            }
         
            Console.ReadKey();
  
        }

но понимаю что это не верно. так как у меня время elapsed_time все время увеличивается
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39121522
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IPmen,

Создать массив на 100 ManualResetEvent (или Auto, как хотите), каждый эвент передаете в вебклиент, в ДанлоадСтрингКомплитед устанавливаете для переданного эвента сигнал.

Стопвач нужно вынести из цикла. Перед тем, как вызвать стоп на стопвотче, делаем WaitAll на все 100 эвентов.

берем элапседтайм и делим на 100, получаем среднее время

ЗЫ IPman :-)
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39121561
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕМНИП у Рихтера что-то было на эту тему. Есть какое-то исскуственное ограничение на кол-во одновременных запросов к одному серверу. Вроде всего 2 по дефолту.
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39121736
VAlexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Согласен с Dima T.
Нужно добавить в app.config:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 
<configuration>
...
<system.net> 
  <connectionManagement> 
   <add address="*" maxconnection="100" /> 
  </connectionManagement> 
 </system.net> 
...
</configuration>
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39122097
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79
Стопвач нужно вынести из цикла. Перед тем, как вызвать стоп на стопвотче, делаем WaitAll на все 100 эвентов.

Ага, ага! Он может максимум 64 ждать.
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39122135
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
    static void Main(string[] args)
        {
            const string url = "http://www.weather.gov";
            System.Collections.Concurrent.ConcurrentBag<long> bag = new System.Collections.Concurrent.ConcurrentBag<long>();
           var actions = Enumerable.Range(0, 100).Select<int,Action>(x => 
            {
                return () => 
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    WebClient cli = new WebClient();
                    cli.DownloadStringCompleted += (s, e) => 
                    {
                        stopwatch.Stop();
                        bag.Add(stopwatch.ElapsedMilliseconds);
                    };
                    cli.DownloadString(new Uri(url));
                };
            });
            Parallel.Invoke(actions.ToArray());
            var res = bag.Average();

            Console.ReadLine();
        }
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39122190
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ,

Я сам не проверял, если честно, не было никогда такой необходимости )))
Сейчас перепроверил, да, действительно, не более 64.

Но это легко же обходится. Один эвент и ждем его, + заводим переменную = 99, которой в ДанлоадСтрингКомплитед через Interlocked уменьшаем на 1 и если стало 0, то устанавливаем эвент
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39122233
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79,
Зачем мучаться? Task.WaitAll не имеет таких ограничений.
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39122376
blest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IPmen,

у Вас классический пример эффекта замыкания в C#

В C# 5.0 для foreach эту фичу немного изменили (в цикле for она все еще присутствует)

Поэтому видоизмените ваш код

Код: c#
1.
for (int i = 1; i <= 100; i++){


на
Код: c#
1.
 foreach(var i in Enumerable.Range(0, 100)){



и почувствуйте разницу
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39123289
IPmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо а что если сделать через Prallel For

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
  Parallel.For(0, n, i =>
            {
                Console.WriteLine("Request " + i);

                var w = new Stopwatch(); 
                try
                {
                    w.Start();



                    var request = (HttpWebRequest)WebRequest.Create(new Uri(url));
                    request.Method = "POST";
                    request.ContentType = "application/xml";
                    request.Accept = "application/xml";

                    var redmineRequestXml =
                        new XElement("Context",
                        new XElement("TypeName", "Menu"),
                        new XElement("Language", "En")
                    );

                    var bytes = Encoding.UTF8.GetBytes(redmineRequestXml.ToString());
                    request.ContentLength = bytes.Length;

                    using (var putStream = request.GetRequestStream())
                    {
                        putStream.Write(bytes, 0, bytes.Length);
                    }

                    using (var response = (HttpWebResponse)request.GetResponse())
                    using (var reader = new StreamReader(response.GetResponseStream()))
                    {
                      var ss =  reader.ReadToEnd();
                    }
                    w.Stop();
                    // Add period ms for unse request
                    totalTimes[i] += w.ElapsedMilliseconds;




                    Console.WriteLine("Response: " + i + " Time:" + w.ElapsedMilliseconds);
                }
                catch (WebException we)
                {
                    w.Stop();
                    totalTimes[i] += w.ElapsedMilliseconds;

                    var badResponseCode = (int)((HttpWebResponse)we.Response).StatusCode;
                    var badResponseString = ((HttpWebResponse)we.Response).StatusCode.ToString();
                    Console.WriteLine("Error Response: " + badResponseCode + " " + badResponseString);
                }

            });



В таком виде заметил интересную вещь. точнее Console.WriteLine("Request " + i); выдаёте нумерацию по очереди 1,2,3,4,5,6 и т.д разве код е должен внутри
Код: c#
1.
2.
  Parallel.For(0, n, i =>
            {})



не должен выполнится асинхронно?
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39123299
IPmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
IPmenВсем спасибо а что если сделать через Prallel For

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
  Parallel.For(0, n, i =>
            {
                Console.WriteLine("Request " + i);

                var w = new Stopwatch(); 
                try
                {
                    w.Start();



                    var request = (HttpWebRequest)WebRequest.Create(new Uri(url));
                    request.Method = "POST";
                    request.ContentType = "application/xml";
                    request.Accept = "application/xml";

                    var redmineRequestXml =
                        new XElement("Context",
                        new XElement("TypeName", "Menu"),
                        new XElement("Language", "En")
                    );

                    var bytes = Encoding.UTF8.GetBytes(redmineRequestXml.ToString());
                    request.ContentLength = bytes.Length;

                    using (var putStream = request.GetRequestStream())
                    {
                        putStream.Write(bytes, 0, bytes.Length);
                    }

                    using (var response = (HttpWebResponse)request.GetResponse())
                    using (var reader = new StreamReader(response.GetResponseStream()))
                    {
                      var ss =  reader.ReadToEnd();
                    }
                    w.Stop();
                    // Add period ms for unse request
                    totalTimes[i] += w.ElapsedMilliseconds;




                    Console.WriteLine("Response: " + i + " Time:" + w.ElapsedMilliseconds);
                }
                catch (WebException we)
                {
                    w.Stop();
                    totalTimes[i] += w.ElapsedMilliseconds;

                    var badResponseCode = (int)((HttpWebResponse)we.Response).StatusCode;
                    var badResponseString = ((HttpWebResponse)we.Response).StatusCode.ToString();
                    Console.WriteLine("Error Response: " + badResponseCode + " " + badResponseString);
                }

            });



В таком виде заметил интересную вещь. точнее Console.WriteLine("Request " + i); выдаёте нумерацию по очереди 1,2,3,4,5,6 и т.д разве код е должен внутри
Код: c#
1.
2.
  Parallel.For(0, n, i =>
            {})



не должен выполнится асинхронно?

Прошу прощения не так написал. у меня код Parallel.For( вызывается несколько раз в цикле,

Код: c#
1.
2.
3.
4.
       for (var i = 1; i <= 10; i++)
            {
                    Parallel.For(0, n, k=>
                             {     Console.WriteLine("Request" + i);

и строка Console.WriteLine("Request" + i); выдаёте нумерацию по очереди 1,2,3,4,5,6 и т.д до 10. разве так должно быть?
...
Рейтинг: 0 / 0
Получить данные с потоков
    #39123908
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IPmen,
Пиши еще в консоль идентификатор текущего потока. Если они разные, по выполняется ||.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить данные с потоков
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]