Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 16438|Відповідь: 0

[WinForm] C# багатопотокова розробка

[Копіювати посилання]
Опубліковано 11.12.2019 12:08:45 | | |
Завдання — завантажити майже 40 000 аудіозаписів з Alibaba Cloud у локальну зону, і одне завантаження відбувається дуже повільно, тому я хочу використовувати багатопотокове завантаження і виділяти 20 потоків для завантаження одночасно, заощаджуючи багато часу
          Програма класу
    {

        static void Main(string[] args) {
            String sql = "вибрати en_audio,us_audio з t_audio LIMIT 198";
            MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql);         
            List<String> sList = новий List<String>();
            sList.Add("https://qutifen-qudao.oss-cn-beijing.aliyuncs.com/mfg/audio/v3/1abacus_en.ogg");
            sList.Add("https://qutifen-qudao.oss-cn-beijing.aliyuncs.com/mfg/audio/v3/2abacus_en.ogg");
            if (mySqlDataReader.HasRows)
            {
                тоді як (mySqlDataReader.Read())
                {                 
                    sList.Add(mySqlDataReader.GetString(0));
                    sList.Add(mySqlDataReader.GetString(1));
                }
            }              
            Console.WriteLine(sList.Count);
            Секундомір = новий секундомір();
            секундомір. Start();
            ThreadStart(sList);
            WaitHandle.WaitAll(чекає);  Усі потоки очікування для прослуховування встановлені перед виконанням наступного коду, інакше вони чекатимуть тут
            секундомір. Stop();
            Console.WriteLine($"Time-henting{секундомір. ElapsedMilliseconds}milliseconds»);
            Console.ReadKey();


        }
       статична різьба[] різьба = нова різьба[20];
        статичний WaitHandle[] чекає = новий WaitHandle[20];
        public static void ThreadStart(List<String> nums) {
                  Призначити потоки
            для (int i=0; i<20; i++) {
                threads[i] = новий Thread(DownLoadFile);
                waits[i] = новий AutoResetEvent(false);

            }
                 Призначте дані кожному потоку для виконання та початку виконання
            для (int i = 0; Мені < 20; i++)
            {
                якщо (i== потоки. Довжина-1) {
                    VAR Retult = Nums. Skip(nums. Count / 20 * i). Візьміть(nums. Лічимо-число. Count / 20*i). ToList();
                    threads[i]. Start (новий Objpt()
                    {
                        sList = ретульт,
                        WaitHandle = чекає[i],
                        ThreadIndex = i
                    });
                }
                інше {
                  VAR retult= Nums. Skip(nums. Count / 20 * i). Візьміть(nums. Count / 20). ToList();
                    threads[i]. Start(new Objpt() {
                     sList = retult,
                     WaitHandle=waits[i],
                     ThreadIndex=i
                    });
                }

            }
        }

        public static void DownLoadFile(Object obj)
        {
            int count = 0;
            Objpt optObj = (obj як Objpt);
            var sList = optObj.sList;
            Console.WriteLine($"Thread{optObj.ThreadIndex} started";
            foreach (var url у sList)
            {
                спробуйте
                {
                    count++;
                    var arrs = url. Спліт('/');
                    WebRequest request = WebRequest.Create(url);
                    HttpWebResponse res = (HttpWebResponse)запит. GetResponse();
                    WebResponse rep = запит. GetResponse();           
                    якщо (рез. StatusCode.ToString() == "OK")
                    {
                        Відповідь потокуStream = відповідь. GetResponseStream();
                        using (FileStream fsWrite = новий FileStream($"F:/Audio/v4/{arrs[arrs[arrs. Довжина - 2]}/{arrs[arrs. Довжина - 1]}", FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            byte[] buffer = новий байт[відповідь. ContentLength];
                            хоча (правда)
                            {
                                Повертає кількість фактично прочитаних байтів цього разу
                                int r = відповідьStream.Read(buffer, 0, buffer. Довжина);
                                якщо (r == 0)
                                {
                                    перерва;
                                }
                                fsWrite.Write(buffer, 0, r); Пиши

                            }
                        }
                    }
                    якщо (кількість % 20 == 0 || count == sList.Count)
                    //{
                    Console.WriteLine($"Thread{optObj.ThreadIndex} оброблений:{count}");
                    //}

                }
                catch (виняток, наприклад)
                {
                    string strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log";
                    якщо (! System.IO.File.Exists(strErrorLogFile))
                        System.IO.File.WriteAllText (strErrorLogFile, "//System ErrorLog File\r\n");
                    object objSql = "thread" + optObj.ThreadIndex.ToString() + ex. Повідомлення;
                    System.IO.File.AppendAllText(strErrorLogFile, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + objSql.ToString() + url + "\r\n");

                }

            }
            Console.WriteLine($"Thread{optObj.ThreadIndex} закінчується");
            (optObj.WaitHandle як AutoResetEvent). Set();  Метод множини полягає у позначенні, коли потік закінчується
        }
    }

     публічний клас Objpt {
        public<String> List sList { get; декорація; }
        public WaitHandle WaitHandle { get; декорація; }
        public int ThreadIndex { get; декорація; }

    }





Попередній:net/c# Як реалізувати DNS-захоплення
Наступний:Використання DateTime
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com