この作業は、アリババクラウドから約4万件の音声をローカルエリアにダウンロードすることですが、1回のダウンロードは非常に遅いため、マルチスレッドを使い、同時に20スレッドを割り当てて時間を大幅に節約したいと考えています クラスプログラム {
static void Main(string[] args) { string sql = 「LIMIT 198からen_audio,us_audioを選択t_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)); } } Console.WriteLine(sList.Count); ストップウォッチ ストップウォッチ = 新しいストップウォッチ(); ストップウォッチ。 Start(); ThreadStart(sList); WaitHandle.WaitAll(waits); リッスン待ち内のすべてのスレッドは、次のコードを実行する前に設定されているため、そうでなければここで待機しています ストップウォッチ。 Stop(); Console.WriteLine($"Time-consuming{stopwatch. 経過ミリ秒}ミリ秒"); Console.ReadKey();
} 静的スレッド[] スレッド = 新しいスレッド[20]; static WaitHandle[] waits = 新しいWaitHandle[20]; public static void ThreadStart(List<String> nums) { スレッドの割り当て (整数 i=0; i<20; i++) { threads[i] = 新しいスレッド(DownLoadFile); waits[i] = 新しいAutoResetEvent(false);
} 各スレッドにデータを割り当てて実行を開始します (int i = 0; 私は20<; i++) { もし(i=スレッド)が使えば。 長さ-1) { var retult = nums. スキップ(数字) カウント / 20 * i)。 取っていけ。 カウント・ナムズ。 カウント / 20*i)。 ToList(); スレッド[i]。 スタート(新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) { int count = 0; Objpt optObj = (obj as Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} started"; foreach(sList のvar URL) { やってみて { カウント++; 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. Length - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = 新しいバイト[応答。 ContentLength; while(真) { 今回は実際に読み込まれたバイト数を返します int r = responseStream.Read(buffer, 0, buffer. 長さ); もし (r == 0) { 休憩; } fsWrite.Write(buffer, 0, r); 書く
} } } if(count % 20 == 0 || count == 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 WaitHandle WaitHandle { get; セット; } public int ThreadIndex { get; セット; }
}
|