L'attività da svolgere è scaricare quasi 40.000 audio da Alibaba Cloud verso l'area locale, e un singolo download è molto lento, quindi voglio usare il multithreading e allocare 20 thread da scaricare contemporaneamente, risparmiando molto tempo Programma di classe {
static void Main(string[] args) { string sql = "seleziona en_audio,us_audio da t_audio LIMIT 198 "; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql); List<String> sList = nuova Lista<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) { while (mySqlDataReader.Read()) { sList.Add(mySqlDataReader.GetString(0)); sList.Add(mySqlDataReader.GetString(1)); } } Console.WriteLine(sList.Count); Cronometro = nuovo Cronometro(); Cronometro. Start(); ThreadStart(sList); AspettaManiglia.AspettaTutto(aspetta); Tutti i thread nell'attesa di ascolto sono stati impostati prima di eseguire il codice seguente, altrimenti aspetteranno qui Cronometro. Stop(); Console.WriteLine($"Tempo-consumatore{cronometro. Millisecondi Trascorsi}millisecondi"); Console.ReadKey();
} thread statici[] thread = nuovo thread[20]; statico WaitHandle[] waits = nuovo WaitHandle[20]; public static void ThreadStart(List<String> nums) { Assegna thread per (int i=0; i<20; i++) { threads[i] = nuovo Thread(DownLoadFile); waits[i] = nuovo AutoResetEvent(false);
} Assegna dati a ogni thread da eseguire e avviare l'esecuzione per (int i = 0; Ho < 20; i++) { if (i== threads. Lunghezza-1) { var retult = nums. Salta (nums. Conta / 20 * i). Prendi (num. Conta- numeri. Conta / 20*i). ToList(); threads[i]. Inizio(nuovo Obiettivo() { sList = retult, WaitHandle = aspetta[i], ThreadIndex = i }); } else { var retult= nums. Salta (nums. Conta / 20 * i). Prendi (num. Conteggio / 20). ToList(); threads[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
Public static void DownLoadFile(Object obj) { conteggio int = 0; Objpt optObj = (obj come Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} iniziato"; foreach (var url in sList) { prova { count++; var arrs = URL. Scissione('/'); Richiesta WebRequest = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)richiesta. GetResponse(); WebResponse risposta = richiesta. GetResponse(); se (res. StatusCode.ToString() == "OK") { Risposta del corso d'acqua Flusso = risposta. GetResponseStream(); usando (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs. Lunghezza - 2]}/{arrs[arrs. Lunghezza - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = nuovo byte[risposta. ContenutoLunghezza]; mentre (vero) { Restituisce il numero effettivamente di byte letti questa volta int r = responseStream.Read(buffer, 0, buffer. Lunghezza); if (r == 0) { pausa; } fsWrite.Write(buffer, 0, r); scrivi
} } } if (count % 20 == 0 || count == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} processed:{count}"); //}
} catch (eccezione ex) { stringa strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log"; se (! System.IO.File.Exists(strErrorLogFile)) System.IO.File.WriteAllText(strErrorLogFile, "//System ErrorLog File\r\n"); object objSql = "thread" + optObj.ThreadIndex.ToString() + ex. Messaggio; 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 come AutoResetEvent). Set(); Il metodo set consiste nel segnare quando un thread termina } }
classe pubblica Objpt { public<String> List sList { get; set; } public WaitHandle WaitHandle { get; set; } public int ThreadIndex { get; set; }
}
|