Afacerea care trebuie realizată este să descarc aproape 40.000 de bucăți audio din Alibaba Cloud către zona locală, iar o singură descărcare este foarte lentă, așa că vreau să folosesc multi-threading și să aloc 20 de fire de descărcare simultan, economisind mult timp Programul clasei {
static void Main(string[] args) { string sql = "selectează en_audio,us_audio din t_audio LIMIT 198 "; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql); List<String> sList = List <String>nou(); 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) { în timp ce (mySqlDataReader.Read()) { sList.Add(mySqlDataReader.GetString(0)); sList.Add(mySqlDataReader.GetString(1)); } } Console.WriteLine(sList.Count); Cronometr = cronometru nou(); Cronometru. Start(); ThreadStart(sList); WaitHandle.WaitAll(waits); Toate firele din listen-wait au fost setate înainte de a executa codul următor, altfel vor aștepta aici Cronometru. Stop(); Console.WriteLine($"Consumator de timp{cronometru. ElapsedMilliseconds}milisecunde"); Console.ReadKey();
} fire statice[] thread-uri = thread nou[20]; static WaitHandle[] waits = noul WaitHandle[20]; public static void ThreadStart(List<String> nums) { Atribuie fire pentru (int i=0; i<20; i++) { threads[i] = new Thread(DownLoadFile); waits[i] = New AutoResetEvent(false);
} Atribuie date fiecărui fir de execuție și începe execuția pentru (int i = 0; Am < 20; i++) { if (i== threads. Lungime-1) { var retult = nums. Sari (nums. Numără / 20 * i). Ia (nums. Număr de numere. Număr / 20*i). ToList(); fire[i]. Start(noul Objpt() { sList = retult, WaitHandle = waits[i], ThreadIndex = i }); } altfel { var retult= nums. Sari (nums. Numără / 20 * i). Ia (nums. Număr / 20). ToList(); fire[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
public static void DownLoadFile(Object obj) { număr de inteligență = 0; Objpt optObj = (obj ca Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} started"; foreach (var url în sList) { încearcă { count++; var arrs = URL. Split('/'); Cerere WebRequest = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)solicitare. GetResponse(); Răspuns WebResponse = cerere. GetResponse(); dacă (res. StatusCode.ToString() == "OK") { Răspunsul fluxuluiFlux = răspuns. GetResponseStream(); folosind (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs. Lungime - 2]}/{arrs[arrs. Lungime - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { Octet[] buffer = Octet nou[răspuns. ConținutLungime]; în timp ce (adevărat) { Returnează numărul efectiv de octeți citiți de data aceasta int r = responseStream.Read(buffer, 0, buffer. lungime); if (r == 0) { pauză; } fsWrite.Write(buffer, 0, r); Scrie
} } } dacă (count % 20 == 0 || count == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} procesat:{count}"); //}
} catch (excepție ex) { string strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log"; dacă (! System.IO.File.Exists(strErrorLogFile)) System.IO.File.WriteAllText(strErrorLogFile, "//System ErrorLog File\r\n"); object objSql = "thread" + optObj.ThreadIndex.ToString() + ex. Mesaj; 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 ca AutoResetEvent). Set(); Metoda set este de a marca când se termină un fir de execuție } }
clasa publică Objpt { public<String> List sList { get; set; } public WaitHandle WaitHandle { get; set; } public int ThreadIndex { get; set; }
}
|