Das Geschäft besteht darin, fast 40.000 Audiostücke von der Alibaba Cloud in die lokale Region herunterzuladen, und ein einzelner Download ist sehr langsam, daher möchte ich Multithreading nutzen und 20 Threads gleichzeitig herunterladen, was viel Zeit spart Klassenprogramm {
statische Void Haupt(string[] args) { string sql = "select en_audio,us_audio aus t_audio LIMIT 198 "; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql); Liste<String> sList = neue Liste<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) { während (mySqlDataReader.Read()) { sList.Add(mySqlDataReader.GetString(0)); sList.Add(mySqlDataReader.GetString(1)); } } Console.WriteLine(sList.Count); Stoppuhr = neue Stoppuhr(); Stoppuhr. Start(); ThreadStart(sList); WaitHandle.WaitAll(wartet); Alle Threads im Listen-Wartemodus wurden vor der Ausführung des folgenden Codes gesetzt, ansonsten warten sie hier Stoppuhr. Stop(); Console.WriteLine($"Time-upsinging{stopwatch. ElapsedMilliseconds}millisekunden"); Console.ReadKey();
} statischer Thread[] threads = neuer Thread[20]; statisches WaitHandle[] waits = neuer WaitHandle[20]; öffentliche statische Void ThreadStart(List<String> nums) { Threads zuweisen für (int i=0; i<20; i++) { threads[i] = neuer Thread(DownLoadFile); waits[i] = neuer AutoResetEvent(false);
} Weisen Sie jedem Thread Daten zur Ausführung zu und starten Sie die Ausführung für (int i = 0; Ich < 20; i++) { wenn (i== Threads. Länge-1) { var retult = nums. Skip(nums. Zählen / 20 * i). Take(nums. Zähl-nums. Count / 20*i). ToList(); Threads[i]. Start(neuer Objpt() { sList = retult, WaitHandle = wartet[i], ThreadIndex = i }); } sonst { var retult= nums. Skip(nums. Zählen / 20 * i). Take(nums. Zähle / 20). ToList(); Threads[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
öffentliche statische Void DownLoadFile(Object obj) { Int Count = 0; Objpt optObj = (obj als Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} gestartet"; foreach (var URL in sList) { Versuch es { Zählen++; var arrs = URL. Split('/'); WebRequest-Anfrage = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)Anfrage. GetResponse(); WebResponse-Antwort = Anfrage. GetResponse(); wenn (res. StatusCode.ToString() == "OK") { Stream responseStream = response. GetResponseStream(); using (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs. Länge - 2]}/{arrs[arrs. Länge - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = neues byte[response. ContentLength]; während (wahr) { Gibt die Anzahl der tatsächlich gelesenen Bytes zurück, die diesmal tatsächlich gelesen wurden int r = responseStream.Read(buffer, 0, buffer. Länge); wenn (r == 0) { Unterbrechung; } fsWrite.Write(buffer, 0, r); schreib
} } } wenn (zählen % 20 == 0 || zählen == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} verarbeitet:{count}"); //}
} catch (Ausnahme z. B.) { string strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log"; wenn (! System.IO.File.Exists(strErrorLogFile)) System.IO.File.WriteAllText(strErrorLogFile, "//System ErrorLog File\r\n"); object objSql = "thread" + optObj.ThreadIndex.ToString() + ex. Nachricht; 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} endet"); (optObj.WaitHandle als AutoResetEvent). Set(); Die Set-Methode bedeutet, zu markieren, wann ein Thread endet } }
öffentliche Klasse Objpt { public List<String> sList { get; Set; } public WaitHandle WaitHandle { get; Set; } public int ThreadIndex { get; Set; }
}
|