O negócio a ser feito é baixar quase 40.000 áudios do Alibaba Cloud para a área local, e um único download é muito lento, então quero usar multithreading e alocar 20 threads para baixar ao mesmo tempo, economizando muito tempo Programa da turma {
static void Main(string[] args) { string sql = "selecione en_audio.us_audio de t_audio LIMITE 198"; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql); Lista<String> sLista = nova 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) { enquanto (mySqlDataReader.Read()) { sList.Add(mySqlDataReader.GetString(0)); sList.Add(mySqlDataReader.GetString(1)); } } Console.WriteLine(sList.Count); Croômetro = novo cronômetro(); Cronometre. Start(); ThreadStart(sList); WaitHandle.WaitAll(waits); Todas as threads na espera de escuta foram definidas antes de executar o código a seguir, caso contrário, estarão esperando aqui Cronometre. Stop(); Console.WriteLine($"Demorado{cronômetro. Milissegundos decorridos}milissegundos"); Console.ReadKey();
} threads estáticos[] threads = novo thread[20]; WaitHandle[] waits = new WaitHandle[20]; public static void ThreadStart(List<String> nums) { Atribuir threads para (int i=0; i<20; i++) { threads[i] = nova Thread(DownLoadFile); espera[i] = novo AutoResetEvent(false);
} Atribua dados a cada thread para executar e iniciar a execução para (int i = 0; Eu < 20; i++) { if (i== threads. Comprimento-1) { var retult = nums. Pular (nums. Conte / 20 * i). Veja (números de menos. Conde- números. Contagem / 20*i). ToList(); threads[i]. Start(novo Objpt() { sList = retult, WaitHandle = espera[i], ThreadIndex = i }); } else { var retult= nums. Pular (nums. Conte / 20 * i). Veja (números de menos. Contagem / 20). ToList(); threads[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
empty estático público DownLoadFile(Object obj) { contagem de inteligência = 0; Objpt optObj = (obj como Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} iniciado"; foreach (var url em sList) { tente { count++; var arrs = URL. Divisão('/'); Solicitação WebRequest = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)solicitação. GetResponse(); Resposta WebResponse = solicitação. GetResponse(); se (res. StatusCode.ToString() == "OK") { Resposta do fluxo Fluxo = resposta. GetResponseStream(); usando (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs. Comprimento - 2]}/{arrs[arrs. Comprimento - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { Byte[] buffer = novo byte[resposta. ConteúdoComprimento]; enquanto (verdadeiro) { Dessa vez, retorna o número de bytes realmente lidos. int r = responseStream.Read(buffer, 0, buffer. Comprimento); if (r == 0) { intervalo; } fsWrite.Write(buffer, 0, r); Escreva
} } } if (count % 20 == 0 || count == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} processed:{count}"); //}
} captura (exceção ex) { string 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. Mensagem; 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} termina"); (optObj.WaitHandle como AutoResetEvent). Set(); O método set é marcar quando uma thread termina } }
classe pública Objpt { public List<String> sList { get; set; } public WaitHandle WaitHandle { get; set; } public int ThreadIndex { get; set; }
}
|