Задачата, която трябва да се извърши, е да се изтеглят почти 40 000 аудио парчета от Alibaba Cloud в местния район, а едно изтегляне е много бавно, затова искам да използвам мултитрединг и да отделя 20 нишки за изтегляне едновременно, спестявайки много време Програма на класа {
static void Main(string[] args) { низ 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(чака); Всички нишки в изчакването за слушане са зададени преди изпълнение на следващия код, иначе ще чакат тук хронометър. Стоп(); Console.WriteLine($"Time-coming{хронометър. ElapsedMilliseconds}milliseconds"); Console.ReadKey();
} статична нишка[] нишки = нова нишка[20]; статичен WaitHandle[] чака = нов WaitHandle[20]; public static void ThreadStart(List<String> nums) { Присвояване на нишки за (int i=0; i<20; i++) { нишки[i] = нова нишка(DownLoadFile); waits[i] = нов AutoResetEvent(false);
} Задайте данни на всяка нишка за изпълнение и започване на изпълнението за (int i = 0; < на 20; i++) { ако (i== нишки. Дължина-1) { VAR Retult = Nums. Skip(nums. Брой / 20 * i). Вземи (nums. Бройте-числа. Брой / 20*i). ToList(); нишки[i]. Start(new Objpt() { sList = ретулт, WaitHandle = чакания[i], ThreadIndex = i }); } else { var retult= nums. Skip(nums. Брой / 20 * i). Вземи (nums. Брой / 20). ToList(); нишки[i]. Start(new Objpt() { sList= ретулт, WaitHandle=waits[i], ThreadIndex=i }); }
} }
public static void DownLoadFile(обект obj) { int брой = 0; Objpt optObj = (obj като Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} started"; foreach (var url в sList) { Опитай { count++; var arrs = url. Split('/'); WebRequest request = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)заявка. GetResponse(); WebResponse отговор = заявка. GetResponse(); Ако (рез. StatusCode.ToString() == "OK") { Stream responseStream = отговор. GetResponseStream(); използвайки (FileStream fsWrite = нов FileStream($"F:/Audio/v4/{arrs[arrs[arrs. Дължина - 2]}/{arrs[arrs. Дължина - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { байт[] буфер = нов байт[отговор. ContentLength]; докато (вярно) { Връща броя на реално прочетените байтове този път int r = отговорStream.Read(buffer, 0, buffer. Дължина); ако (r == 0) { прекъсване; } fsWrite.Write(buffer, 0, r); Пиши
} } } ако (процент брой 20 == 0 || брой == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} processed:{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 = "нишка" + 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} ends"); (optObj.WaitHandle като AutoResetEvent). Set(); Методът на множеството е да се отбележи кога нишка приключва } }
публичен клас Objpt { public<String> List sList { get; декорация; } public WaitHandle WaitHandle { get; декорация; } public int ThreadIndex { get; декорация; }
}
|