진행할 일은 알리바바 클라우드에서 지역 지역으로 약 40,000개의 오디오를 다운로드하는 것인데, 단일 다운로드는 매우 느리기 때문에 멀티스레딩을 사용해 20개의 스레드를 동시에 할당해 시간을 많이 절약하고 싶습니다 수업 프로그램 {
static void Main(string[] args) { 문자열 SQL = "LIMIT 198에서 t_audio en_audio,us_audio 선택; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql); 목록<String> sList = 새 목록<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)); } } 콘솔.WriteLine(sList.Count); 스톱워치 스톱워치 = 새로운 스톱워치(); 스톱워치. Start(); ThreadStart(sList); WaitHandle.WaitAll(대기); 리치 대기 내 모든 스레드는 다음 코드를 실행하기 전에 설정되어 있으며, 그렇지 않으면 여기서 대기 중입니다 스톱워치. Stop(); Console.WriteLine($"Time-소모{스톱워치. 경과밀리초}밀리초"); Console.ReadKey();
} 정적 스레드[] 스레드 = 새 스레드[20]; static WaitHandle[] waits = new WaitHandle[20]; public static void ThreadStart(List<String> nums) { 스레드 할당 (int i=0; i<20; i++) { threads[i] = 새로운 스레드(DownLoadFile); waits[i] = new AutoResetEvent(false);
} 각 스레드에 데이터를 할당하여 실행하고 실행을 시작하세요 (정수: i = 0; 저는 20< 되었고; i++) { 만약 (i== 스레드. 길이-1) { var retult = nums. 건너뛰세요. 카운트 / 20 * i). 가져가세요. 카운트- 넘스. 카운트 / 20*i). ToList(); 스레드[i]. Start(새로운 Objpt() { sList = retult, WaitHandle = waits[i], ThreadIndex = i }); } 그렇지 않으면 { var retult= nums. 건너뛰세요. 카운트 / 20 * i). 가져가세요. 카운트 / 20). ToList(); 스레드[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
public static void DownLoadFile(Object obj) { 정수 = 0; Objpt optObj = (obj, Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} started"; foreach (sList의 var URL) { 시도해 { count++; var arrs = URL. 스플릿('/'); WebRequest request = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)요청. GetResponse(); WebResponse 응답 = 요청. GetResponse(); 만약 (res. StatusCode.ToString() == "OK") { 스트림 응답Stream = 응답. GetResponseStream(); using (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs. 길이 - 2]}/{arrs[arrs. 길이 - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { 바이트[] 버퍼 = 새로운 바이트[응답. ContentLength]; while (참) { 이번에는 실제로 읽은 바이트 수를 반환합니다 int r = responseStream.Read(buffer, 0, buffer. 길이; 만약 (r == 0) { 브레이크; } fsWrite.Write(buffer, 0, r); 쓰기
} } } 만약 (카운트 % 20 == 0 || 카운트 == sList.Count) //{ Console.WriteLine($"Thread{optObj.ThreadIndex} processed:{count}"); //}
} catch (예외 예) { string strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log"; 만약 (! System.IO.File.Exists(strErrorLogFile)) System.IO.File.WriteAllText(strErrorLogFile, "//System ErrorLog File\r\n"); object objSql = "thread" + optObj.ThreadIndex.ToString() + ex. 메시지; 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을 AutoResetEvent로 사용). Set(); Set 메서드는 스레드가 종료될 때 표시하는 것입니다 } }
공공 클래스 Objpt { 공개 목록<String> sList { get; 세트; } public 대기핸들 대기핸들 { get; 세트; } public int ThreadIndex { get; 세트; }
}
|