L’activité à réaliser consiste à télécharger près de 40 000 morceaux audio d’Alibaba Cloud vers la zone locale, et un seul téléchargement est très lent, donc je veux utiliser le multithreading et allouer 20 threads à télécharger simultanément, ce qui fait gagner beaucoup de temps Programme de la classe {
vide statique Main(string[] args) { string sql = « sélectionner en_audio,us_audio parmi t_audio LIMIT 198 » ; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql) ; Liste<String> sListe = nouvelle <String>Liste() ; 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) { tandis que (mySqlDataReader.Read()) { sList.Add(mySqlDataReader.GetString(0)) ; sList.Add(mySqlDataReader.GetString(1)) ; } } Console.WriteLine(sList.Count) ; Chronomètre = nouveau chronomètre() ; Chronomètre. Start() ; ThreadStart(sList) ; AttendsHandle.AttendsTout(attends) ; Tous les threads dans l’écoute d’attente ont été définis avant d’exécuter le code suivant, sinon ils attendront ici Chronomètre. Stop() ; Console.WriteLine($"Chronomètre{chronomètre. MillisecondesÉcoulées}millisecondes ») ; Console.ReadKey() ;
} Fils statiques[] = nouveau Fil[20] ; statique WaitHandle[] waits = nouveau WaitHandle[20] ; public static void ThreadStart(List<String> nums) { Assigner des threads pour (int i=0 ; i<20 ; i++) { threads[i] = nouveau Thread(DownLoadFile) ; waits[i] = nouvel AutoResetEvent(faux) ;
} Assigner des données à chaque thread pour exécuter et lancer l’exécution pour (int i = 0 ; J’ai < 20 ans ; i++) { if (i== threads. Longueur-1) { var retult = nums. Sauter (nums. Compte / 20 * i). Prenons (nums. Compte- nums. Compte / 20*i). ToList() ; fils[i]. Start(nouvel Objpt() { sList = retult, WaitHandle = attends[i], ThreadIndex = i }); } else { var retult= nums. Sauter (nums. Compte / 20 * i). Prenons (nums. Compte / 20). ToList() ; fils[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
vide statique public DownLoadFile(Object obj) { compte d’ints = 0 ; Objpt optObj = (obj comme Objpt) ; var sList = optObj.sList ; Console.WriteLine($"Thread{optObj.ThreadIndex} started » ; foreach (url var dans sList) { essaie { compte++ ; var arrs = URL. Split('/') ; RequêteRequêteRequête = RequêteRéseauCré(url) ; HttpWebResponse res = (HttpWebResponse)request. GetResponse() ; Réponse WebResponse = demande. GetResponse() ; si (res. StatusCode.ToString() == « OK ») { Réponse du ruisseauFlux = réponse. GetResponseStream() ; using (FileStream fsWrite = new FileStream($"F :/Audio/v4/{arrs[arrs. Longueur - 2]}/{arrs[arrs. Longueur - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { Octet[] tampon = nouvel octet[réponse. ContenuLongueur ; tandis que (vrai) { Retourne le nombre d’octets réellement lus cette fois int r = responseStream.Read(buffer, 0, buffer. Length) ; if (r == 0) { pause ; } fsWrite.Write(buffer, 0, r) ; Écrire
} } } if (count % 20 == 0 || count == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} processed :{count} ») ; //}
} catch (Exception ex) { string strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log » ; si ( ! System.IO.File.Exists(strErrorLogFile)) System.IO.File.WriteAllText (strErrorLogFile, « //System ErrorLog File\r\n ») ; object objSql = « thread » + optObj.ThreadIndex.ToString() + ex. Message; System.IO.File.AppendAllText(strErrorLogFile, DateTime.Now.ToString(« yyyy-MM-dd HH :mm :ss ») + « \t » + objSql.ToString() + URL + « \r\n ») ;
}
} Console.WriteLine($"Thread{optObj.Index} ends ») ; (optObj.WaitHandle en tant qu’AutoResetEvent). Set() ; La méthode set consiste à marquer quand un thread se termine } }
classe publique Objpt { public List<String> sList { get ; set ; } public WaitHandle WaitHandle { get ; set ; } public int ThreadIndex { get ; set ; }
}
|