Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не получается распараллелить Task / 25 сообщений из 28, страница 1 из 2
16.05.2017, 12:45
    #39453737
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Всем привет, пишу парсинг курсов ЦБ, и нужно реализовать метод массового получения курсов за определенный временной интервал.
Распараллелил этот процесс, чтобы ускорить его, однако по скорости выполнения получается точно также, как и и через последовательное выполение. Подсажите плиз, что не так.
Код: 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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
 static void Main(string[] args)
        {
            try
            {
				//AsyncContext- класс для запуска асинхронных методов в консольном приложении
                
				AsyncContext.Run(async () => await AsyncLoadUrlParallel());
           
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message); 
                Console.ReadKey();
            }
        }
		
		
		
		 private static   async Task AsyncLoadUrlParallel()
        {
            IEnumerable<string> urlist = getliststring();
            List<Task> tasklist = new List<Task>();

        var tasks = Parallel.ForEach(urlist,
        async s =>
        {
             Console.WriteLine(s + "--" + await ReadXmlValueAsyncTask(s));
            await ReadXmlValueAsyncTask(s);

        });
		
		
		       private  static  IEnumerable<string> getliststring()
        {
            DateTime start_date = new DateTime(2017, 01, 01);
            DateTime final_date = DateTime.Today;

            CultureInfo culture = CultureInfo.CreateSpecificCulture("ru-RU");
            DateTimeFormatInfo dtfi = culture.DateTimeFormat;
            dtfi.DateSeparator = "/";

            List<string> list_of_url = new List<string>();

			//DateTimeHelper.EachDay- получаем дату каждого дня во временном интервале
            foreach (DateTime day in DateTimeHelper.EachDay(start_date, final_date))
            {
                string xml_path = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=" + day.ToString("dd/MM/yyyy", dtfi); 
                list_of_url.Add(xml_path);

            }
            return list_of_url;

        }
		
		
		 static async Task<decimal> ReadXmlValueAsyncTask(string inputpath)
        {
            decimal p = 0;
            using (XmlReader r = XmlReader.Create(inputpath, new XmlReaderSettings() { Async = true }))
            {
                while (await r.ReadAsync())
                {
                    if (r.NodeType == XmlNodeType.Element)
                    {
                        if (r.LocalName == "Valute")
                        {
                            if (r.GetAttribute("ID") == "R01239")
                            {
                                r.ReadToFollowing("Value");
                                string ps = (string)await r.ReadElementContentAsAsync(typeof(System.String), null);
                                p = Convert.ToDecimal(ps);
                            }
                        }
                    }
                }
            }
            return p;
        }
		
		
	// последовательный вариант загрузки 
 static void Main(string[] args)
	{
            try
            {
                DateTime start_date = new DateTime(2017, 01, 01);
                DateTime final_date = DateTime.Today;

                CultureInfo culture = CultureInfo.CreateSpecificCulture("ru-RU");
                DateTimeFormatInfo dtfi = culture.DateTimeFormat;
                dtfi.DateSeparator = "/";

                foreach (DateTime day in DateTimeHelper.EachDay(start_date, final_date))
                {
                        string xml_path = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=" + day.ToString("dd/MM/yyyy", dtfi);
                       Console.WriteLine(day.ToString("dd/MM/yyyy", dtfi) + "  " + AsyncContext.Run(() => ReadXmlValueAsyncTask(xml_path)));

                }         
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message); 
                Console.ReadKey();
            }
        }
	
...
Рейтинг: 0 / 0
16.05.2017, 13:39
    #39453784
Pallaris
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_sub
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
        var tasks = Parallel.ForEach(urlist,
        async s =>
        {
             Console.WriteLine(s + "--" + await ReadXmlValueAsyncTask(s));
            await ReadXmlValueAsyncTask(s);

        });
		



Зачем два раза дергать одно и то же?
...
Рейтинг: 0 / 0
16.05.2017, 14:05
    #39453808
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Pallaris,
конечно дергать 2 раза не надо- при написании сообщения на форум лишнее раскоментировал. При контрольном замере использовал одиночный вызов метода ReadXmlValueAsyncTask(s). Для замера использовал время выполнения между брекпоинтами.
...
Рейтинг: 0 / 0
16.05.2017, 17:15
    #39453996
Pallaris
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Честно говоря не знал, что XmlReader может напрямую с urla забирать xmlины.

Ну лично я не вижу, почему оно не идет быстрее. Может, сервер не дает спамить запросы?
Для замера времени лучше пользовать Stopwatch
Можно попробовать по-другому - параллельно скачивать xmlины, и по получении парсить.
...
Рейтинг: 0 / 0
16.05.2017, 17:58
    #39454039
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_sub,

vb_sub
Код: c#
1.
2.
// последовательный вариант загрузки 
 static void Main(string[] args)



Ничего не понимаю. Где у тя последовательный вариант загрузки? Чем он принципильно отличается? То что в первом запуск через ForEach? Ты же вызываешь тот же метод, который асинхронный.

Стандартный вопрос:
Понимаешь ли разницу между многопоточностью и асинхронностью?

Если понимаешь, то пожалуйста, объясни, в чем принципиально различие первого кода и второго. Где ты хотел выиграть время?
...
Рейтинг: 0 / 0
16.05.2017, 18:30
    #39454065
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
ЕМНИП у Рихтера что-то было про встроенные ограничения на одновременное скачивание. Т.е. хоть 100 страниц качай параллельно - все-равно они по очереди будут качаться. И как лечить вроде тоже было написано.
...
Рейтинг: 0 / 0
16.05.2017, 20:31
    #39454142
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
refreg,
если в кратце, то асинхронный вызов, когда код выполнения не дожидается окончания задачи и выходит из метода, если задача не завершена сразу, и продолжает свое выполнение. Когда await задача завершена, то код выполнения возвращается к ней.
Многопоточность- когда я одновременно создаю несколько экземпляров выполняющие определенную работу (в конкретном примере List задач (Task))-по теории эти задачи должны быть распараллелены по процессорам и выполняться независимо друг от друга.
То что Вы видите использования асинхронных методов в коде- это не на них я хотел распараллелить обработку, а за счет Parallel.ForEach.
Вообще на данную мысль меня натолкнуло видео
YouTube Video
...
Рейтинг: 0 / 0
16.05.2017, 20:33
    #39454143
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Dima T, ну если 100 разных компьютеров одновременно запросят курс у ЦБ- вряд ли они будут в одной очереди выполнения. Или Вы считаете, что у них ограничение клиентов на ip?
...
Рейтинг: 0 / 0
16.05.2017, 20:48
    #39454155
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_subDima T, ну если 100 разных компьютеров одновременно запросят курс у ЦБ- вряд ли они будут в одной очереди выполнения. Или Вы считаете, что у них ограничение клиентов на ip?
Не, там речь была про ограничения внутри одного процесса. При чем тут 100 разных компьютеров? Изначально один процесс в вопросе.
Ограничение от .Net, а не ЦБ. Может путаю, но вроде так и пути обхода описаны. Лень перечитывать, Рихтера почитай .
...
Рейтинг: 0 / 0
17.05.2017, 11:58
    #39454510
Lev Limin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_sub, как тут уже выше подметили, у вас нет распараллеливания, все вызовы идут последовательно.
Вам необходимо формировать Task и делать что-то типа Task.Run(...)

Task[] tasks = new Task[количество задач];
После чего формируешь эти задачи и запускаешь.
Вот тогда они будут идти параллельно.

ВОт тут хорошо написано
Limit The Number Of C# Tasks That Run In Parallel

Я делал подобное только с сайтом росреестра. Вместо 15и часов последовательного выгребания, в 10 потоков выгребало всё за 2.5 часа.
...
Рейтинг: 0 / 0
17.05.2017, 18:54
    #39454966
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Lev Liminvb_sub, как тут уже выше подметили, у вас нет распараллеливания, все вызовы идут последовательно.Я думаю, что оба варианта идут параллельно. Поэтому и нет разницы. Точнее можно сказать, посмотреть что скрывается за AsyncContext.Run

И, на всякий случай, цитата с сайта, который делает весь код бессмысленным (хотя, если смысл поупражняться, то это всегда полезно):
cbr.ruExample 2
Пример получения динамики котировок доллара США:
www.cbr.ru/scripts/XML_dynamic.asp? date_req1 =02/03/2001& date_req2 =14/03/2001&VAL_NM_RQ=R01235
date_req1 - date_req2 = Date range
VAL_NM_RQ - unique code (you can get this code from Example 1)
...
Рейтинг: 0 / 0
18.05.2017, 08:02
    #39455102
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
При росте числа потоков растет время на организацию их запуска.
Оптимальное количество одновременно работающих потоков можно выявить для конкретной машины и конкретной задачи.
...
Рейтинг: 0 / 0
18.05.2017, 12:03
    #39455304
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Cat2,
количество потоков= количество процессоров?
...
Рейтинг: 0 / 0
18.05.2017, 12:52
    #39455350
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_subCat2,
количество потоков= количество процессоров?
сумарное количество ядер\конвееров процессоров, ты не учитываешь тот факт, что в 1ин момент времени поток может ничего не делать, + в системе есть кучи другого говна которые будут прерывать твои потоки.
...
Рейтинг: 0 / 0
19.05.2017, 20:42
    #39456489
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_subCat2,
количество потоков= количество процессоров?
Нет. Не факт что ось равномерно разобьет процессы по ядрам. На других ядрах в это время и другие задачи выполняются и ось может решить, что все должно выполнится на одном ядре.

Когда пишешь на LINQ asParalel, то там реально выбирается почти оптимальный баланс процессоров, потому что какой-то план использования строится, а когда сам запускаешь потоки - то это лотерея.
...
Рейтинг: 0 / 0
19.05.2017, 21:41
    #39456499
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Cat2,

всё зависит от того, какая задача многопоточного выполнения перед вами стоит, вот и всё, Linq далеко не всё решается удобно.
...
Рейтинг: 0 / 0
20.05.2017, 08:32
    #39456549
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Roman MejtesCat2,

всё зависит от того, какая задача многопоточного выполнения перед вами стоит, вот и всё, Linq далеко не всё решается удобно.
Разумеется не всегда везет.
...
Рейтинг: 0 / 0
26.05.2017, 09:24
    #39460142
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Чтобы не плодить темы, закину сюда. В общем есть метод, который получает в имя текстового файла, потом его построчно читает и на каждую строчку выполняет команду. В файле порядка 500 строчек, соответственно генерируется 500 задач. Но все равно в сравнении с использованием простого чтения (без создания задача) получается по времени или также или дольше. Подскажите плиз, что неверно в распараллеливании.
Код: 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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
// метод с "многопоточной обработкой"
 public async static Task parse_outAsync(string s)
        {
            using (FileStream sourceStream = new FileStream(s,
            FileMode.Open, FileAccess.Read, FileShare.Read,
            bufferSize: 4096, useAsync: true))
            {
                StringBuilder sb = new StringBuilder();
                byte[] buffer = new byte[0x1000];
                int numRead;
                while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                {
                    string text = Encoding.ASCII.GetString(buffer, 0, numRead);
                    sb.Append(Encoding.ASCII.GetString(buffer, 0, numRead));
                }

                string a = sb.ToString();
                string[] str = a.Split('\n');

                List<Task> tasks = new List<Task>();
				
                object sync = new object();

                Parallel.ForEach(str, (currentitem) =>
                {
                    if (!String.IsNullOrEmpty(currentitem) && !String.IsNullOrWhiteSpace(currentitem))
                        lock (sync)
                        {
                            tasks.Add(Task.Factory.StartNew(() =>
                            {
      

                                Int64 id = default(Int64);
                                string auth_comment = null;
                                string auth_code = null;
                                int i_final = default(int);
                                int i_start = default(Int16);

                                i_final = currentitem.LastIndexOf(",");
                                // ищем позицию последней запятой

                                for (int i = i_final - 1; i >= 1; i += -1)
                                {
                                    if (currentitem.Substring(i, 1) == ",")
                                    {
                                        i_start = i;
                                        break;
                                    }
                                }

                                auth_code = currentitem.Substring(StringHelper.my_instr(currentitem, ",", 5) + 1, StringHelper.my_instr(currentitem, ",", 6) - StringHelper.my_instr(currentitem, ",", 5) - 1);
                                auth_comment = currentitem.Substring(i_start + 1, i_final - i_start - 1);

                                //ищем id 
                                id = Convert.ToInt32(currentitem.Substring(i_final + 1, currentitem.Length - i_final - 1));

                                if (auth_code.Contains(",") || auth_comment.Contains(","))
                                {
                                    Console.WriteLine("Неправильный парсинг");
                                    return;
                                }

                                using (SqlConnection con = new SqlConnection(@"Server=MSSQL;
                                   Database = DataBase;
                                   User Id = user;
                                   Password = u1;
                                   pooling = true"))
                                {
                                    using (SqlCommand cmd = new SqlCommand())
                                    {
                                        cmd.CommandText = "sp";
                                        cmd.CommandType = CommandType.StoredProcedure;
                                        cmd.Parameters.AddWithValue("@id", id);
                                        cmd.Parameters.AddWithValue("@coment", auth_comment);
                                        cmd.Parameters.AddWithValue("@code", auth_code);
                                        cmd.Connection = con;

                                        try
                                        {
                                            if (con.State != ConnectionState.Open)
                                                con.Open();
                                           //  await cmd.ExecuteNonQueryAsync();
                                        }
                                        finally
                                        {
                                            if (con.State != ConnectionState.Closed)
                                                con.Close();
                                        }
                                    }
                                }

                            }));
                        }                       
                }
              );

                Task.WaitAll(tasks.ToArray());
            }
        }

//однопоточная версия

  public  async static Task  parse_out(string s)
        {
          
            Int64 id = default(Int64);
            string auth_comment = null;
            string auth_code = null;
            int i_final = default(int);
            int i_start = default(Int16);

            using (StreamReader reader = new StreamReader(s, System.Text.Encoding.ASCII))
            {
                while (reader.Peek() >= 0)
                {
                    string str = reader.ReadLine();
                    i_final = str.LastIndexOf(",");
                    // ищем позицию последней запятой

                    for (int i = i_final - 1; i >= 1; i += -1)
                    {
                        if (str.Substring(i, 1) == ",")
                        {
                            i_start = i;
                            break;
                        }
                    }

                    auth_code = str.Substring(StringHelper.my_instr(str, ",", 5)+1, StringHelper.my_instr(str, ",", 6)- StringHelper.my_instr(str, ",", 5)-1);
                    auth_comment = str.Substring(i_start + 1, i_final - i_start - 1);

                    //ищем id 
                    id = Convert.ToInt32(str.Substring(i_final + 1, str.Length - i_final - 1));

                    if (auth_code.Contains(",") || auth_comment.Contains(","))
                    {
                        Console.WriteLine("Неправильный парсинг"); 
                        return;
                    }

                    using (SqlConnection con = new SqlConnection(@"Server=MSSQL;
                                   Database = DataBase;
                                   User Id = user;
                                   Password = u1;
                                   pooling = true"))
                    {
                        using (SqlCommand cmd = new SqlCommand())
                        {
                            cmd.CommandText = "sp";
                            cmd.CommandType = CommandType.StoredProcedure;
                            cmd.Parameters.AddWithValue("@id", id);
                            cmd.Parameters.AddWithValue("@coment", auth_comment);
                            cmd.Parameters.AddWithValue("@auth_code", auth_code);
                            cmd.Connection = con;

                            try
                            {
                                if (con.State != ConnectionState.Open)
                                   con.Open();
                                // await cmd.ExecuteNonQueryAsync();
                            }
                            finally
                            {
                                if (con.State != ConnectionState.Closed)
                                    con.Close();
                            }
                        }
                    }
                }
            }    
        }



При однопоточном выполении 26 мс, при "многопоточном"- 45. Я подозреваю, что время на создание и обработку Taskов перекрывает весь выйгрыш от многопоточности, то тогда какого правила придерживаться? Создавать таски, только если их количесвто меньше количества процессоров?
...
Рейтинг: 0 / 0
26.05.2017, 10:19
    #39460208
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_sub
Код: c#
1.
lock (sync)

И где у тя параллельная обработка?
...
Рейтинг: 0 / 0
26.05.2017, 11:43
    #39460290
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_subПри однопоточном выполении 26 мс, при "многопоточном"- 45. Я подозреваю, что время на создание и обработку Taskов перекрывает весь выйгрыш от многопоточности, то тогда какого правила придерживаться? Создавать таски, только если их количесвто меньше количества процессоров?
У тебя выводы как в анекдотеОпыт 1-й: берем таракана, отрываем ему 2-е ноги, свистим таракан убегает!
Опыт 2-й: берем отрываем таракану еще 2-е ноги, свистим таракан убегает!
Опыт 3-й: берем отрываем таракану последние ноги, свистим таракан стоит!

Вывод: таракан без ног не слышит!

Твои таски последовательно выполняются, см. пост выше. Но и это не тормоз.
Тормоз у тебя в работе с БД. Уменьши количество обращений к БД до минимума, в идеале до одного.
...
Рейтинг: 0 / 0
26.05.2017, 11:53
    #39460295
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Dima T,
изначально было без lock, но в листе tasks тогда появлялась задача null и код падал с ошибкой "Массив задач включал по меньшей мере один неопределенный (null) элемент"- хз откуда ему там появляться.
Dima T Тормоз у тебя в работе с БД. Уменьши количество обращений к БД до минимума что-то вроде bulk update?
...
Рейтинг: 0 / 0
26.05.2017, 11:57
    #39460302
petalvik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
vb_subВ общем есть метод, который получает в имя текстового файла, потом его построчно читает и на каждую строчку выполняет команду.

Тут нужен классический producer-consumer (производитель-потребитель): один поток читает данные и передаёт дальше; второй поток обрабатывает данные; третий поток пишет их в базу. В современном .NET это сверхудобно делается конвейером ( Pipelines ).

Итого, это может выглядеть как-то так:

Код: 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.
var inputLines = new BlockingCollection<string>();
var processedLines = new BlockingCollection<Data>();

// Stage #1
var readLines = Task.Factory.StartNew(() =>
{
    try
    {
        foreach (var line in File.ReadLines(filename))
            inputLines.Add(line);
    }
    finally { inputLines.CompleteAdding(); }
});

// Stage #2
var processLines = Task.Factory.StartNew(() =>
{
    try
    {
        foreach (var line in inputLines.GetConsumingEnumerable())
        {
            var data = Parse(line);
            processedLines.Add(data);
        }
    }
    finally { processedLines.CompleteAdding(); }
});

// Stage #3
var writeLines = Task.Factory.StartNew(() =>
{
    try
    {
        foreach (var data in processedLines.GetConsumingEnumerable())
        {
            // запись data в базу
        }
    }
    finally { // Close connection }
});

Task.WaitAll(readLines, processLines, writeLines);



Потом нужно разобраться, какая именно из этих трёх стадий наиболее затратна, её и параллелить. Чтение с диска параллелить смысла нет: физический носитель один, всё ограничено его скоростью работы.

Запись в базу, аналогично, скорей всего, параллелить смысла нет. Разве что перейти на BULK INSERT .

А вот среднюю стадию можно попробовать ускорить. Применить либо Parallel.ForEach, либо AsParallel().

vb_subЯ подозреваю, что время на создание и обработку Taskов перекрывает весь выйгрыш от многопоточности

Именно!

Если тело задачи выполняется очень быстро, то затраты на её создание превысят выгоды. В таком случае нужно в каждой задаче обрабатывать не один элемент, а диапазон. Тут нужно смотреть в сторону Partitioner.Create - метод разбивает последовательность на диапазон значений, каждый из которых передаём на выполнение таскам.
...
Рейтинг: 0 / 0
26.05.2017, 11:58
    #39460303
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Хотя бы убери установку соединения с БД перед каждым запросом.
Код: 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.
56.
57.
58.
59.
60.
61.
//однопоточная версия

  public  async static Task  parse_out(string s)
        {
          
            Int64 id = default(Int64);
            string auth_comment = null;
            string auth_code = null;
            int i_final = default(int);
            int i_start = default(Int16);

                    using (SqlConnection con = new SqlConnection(@"Server=MSSQL;
                                   Database = DataBase;
                                   User Id = user;
                                   Password = u1;
                                   pooling = true"))
                    {

            using (StreamReader reader = new StreamReader(s, System.Text.Encoding.ASCII))
            {
                while (reader.Peek() >= 0)
                {
                    string str = reader.ReadLine();
                    i_final = str.LastIndexOf(",");
                    // ищем позицию последней запятой

                    for (int i = i_final - 1; i >= 1; i += -1)
                    {
                        if (str.Substring(i, 1) == ",")
                        {
                            i_start = i;
                            break;
                        }
                    }

                    auth_code = str.Substring(StringHelper.my_instr(str, ",", 5)+1, StringHelper.my_instr(str, ",", 6)- StringHelper.my_instr(str, ",", 5)-1);
                    auth_comment = str.Substring(i_start + 1, i_final - i_start - 1);

                    //ищем id 
                    id = Convert.ToInt32(str.Substring(i_final + 1, str.Length - i_final - 1));

                    if (auth_code.Contains(",") || auth_comment.Contains(","))
                    {
                        Console.WriteLine("Неправильный парсинг"); 
                        return;
                    }

                        using (SqlCommand cmd = new SqlCommand())
                        {
                            cmd.CommandText = "sp";
                            cmd.CommandType = CommandType.StoredProcedure;
                            cmd.Parameters.AddWithValue("@id", id);
                            cmd.Parameters.AddWithValue("@coment", auth_comment);
                            cmd.Parameters.AddWithValue("@auth_code", auth_code);
                            cmd.Connection = con;

                        }
                    }
                }
            }    
        }


И многопоточность тут не нужна, т.к. код простой и затраты на создание таска превышают всю пользу от распараллеливания.
...
Рейтинг: 0 / 0
26.05.2017, 12:57
    #39460367
Addx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Dima TИ многопоточность тут не нужна, т.к. код простой и затраты на создание таска превышают всю пользу от распараллеливания.

Параллельная запись в БД - это бред. Как и парсинг.
Единственный процесс, который имеет смысл распараллеливать - собственно скачивание.
И замерять нужно его, а не все подряд.
...
Рейтинг: 0 / 0
26.05.2017, 13:38
    #39460412
petalvik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не получается распараллелить Task
Народ пишет ответы кто на первый вопрос, кто на второй.

Автора самого бы надо "распараллелить" за то, что не задал второй вопрос отдельной темой.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не получается распараллелить Task / 25 сообщений из 28, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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