Η δουλειά που πρέπει να εκτελεστεί είναι η λήψη σχεδόν 40,000 κομματιών ήχου από το Alibaba Cloud στην τοπική περιοχή και μια μόνο λήψη είναι πολύ αργή, επομένως θέλω να χρησιμοποιήσω multi-threading και να διαθέσω 20 νήματα για λήψη ταυτόχρονα, εξοικονομώντας πολύ χρόνο Πρόγραμμα τάξης {
στατικό κενό Main(string[] args) { συμβολοσειρά sql = "επιλέξτε en_audio,us_audio από t_audio LIMIT 198 "; MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql); List<String> sList = νέα List<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"); αν (mySqlDataReader.HasRows) { ενώ (mySqlDataReader.Read()) { sList.Add(mySqlDataReader.GetString(0)); sList.Add(mySqlDataReader.GetString(1)); } } Console.WriteLine(sList.Count); Χρονόμετρο χρονόμετρο = νέο Χρονόμετρο(); χρονόμετρο. Έναρξη(); ThreadStart(sList); WaitHandle.WaitAll(αναμένει); Όλα τα νήματα στην αναμονή ακρόασης έχουν ρυθμιστεί πριν από την εκτέλεση του παρακάτω κώδικα, διαφορετικά θα περιμένουν εδώ χρονόμετρο. Διακοπή(); Console.WriteLine($"Time-convoring{stopwatch. ElapsedMilliseconds}milliseconds"); Κονσόλα.ReadKey();
} στατικά νήματα νήματος[] = νέο νήμα[20]; στατικό WaitHandle[] αναμονές = νέο WaitHandle[20]; public static void ThreadStart(List<String> nums) { Εκχώρηση νημάτων για (int i=0; Ι<20; i++) { threads[i] = νέο νήμα(DownLoadFile); waits[i] = νέο AutoResetEvent(false);
} Εκχωρήστε δεδομένα σε κάθε νήμα για εκτέλεση και έναρξη εκτέλεσης για (int i = 0; I < 20; i++) { if (i== νήματα. Μήκος-1) { var retult = αριθμοί. Skip(nums. Count / 20 * i). Πάρτε(αριθμ. Αριθμοί. Count / 20*i). ToList(); νήματα[i]. Έναρξη(new Στόχος() { sList = retult, WaitHandle = αναμένει[i], Δείκτης νήματος = i }); } αλλιώς { var retult= nums. Skip(nums. Count / 20 * i). Πάρτε(αριθμ. Count / 20). ToList(); νήματα[i]. Start(new Objpt() { sList= retult, WaitHandle=waits[i], ThreadIndex=i }); }
} }
δημόσιο στατικό κενό DownLoadFile(Αντικείμενο obj) { αριθμός ακέραιων = 0; Objpt optObj = (obj ως Objpt); var sList = optObj.sList; Console.WriteLine($"Thread{optObj.ThreadIndex} ξεκίνησε"; foreach (var url στο sList) { Δοκιμάστε { αριθμός++; var arrs = διεύθυνση URL. Split('/'); WebRequest request = WebRequest.Create(url); HttpWebResponse res = (HttpWebResponse)αίτημα. GetResponse(); WebResponse = αίτημα. GetResponse(); αν (res. StatusCode.ToString() == "ΟΚ") { Απόκριση ροήςΡοή = απόκριση. GetResponseStream(); χρησιμοποιώντας (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs. Μήκος - 2]}/{arrs[arrs. Μήκος - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = νέο byte[response. ContentLength]; ενώ (αληθές) { Επιστρέφει τον αριθμό των byte που πραγματικά διαβάστηκαν αυτή τη φορά 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} επεξεργάστηκε:{count}"); //}
} αλιεύματα (Εξαίρεση π.χ.) { συμβολοσειρά strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log"; αν (! System.IO.File.Exists(strErrorLogFile)) System.IO.File.WriteAllText(strErrorLogFile, "//System ErrorLog File\r\n"); αντικείμενο objSql = "νήμα" + optObj.ThreadIndex.ToString() + π.χ. Μήνυμα; System.IO.File.AppendAllText(strErrorLogFile, DateTime.Now.ToString("εεεε-MM-ηη ΩΩ:λλ:δδ") + "\t" + objSql.ToString() + url + "\r\n");
}
} Console.WriteLine($"Thread{optObj.ThreadIndex} τελειώνει"); (optObj.WaitHandle ως AutoResetEvent). set(); Η μέθοδος set είναι να επισημάνετε πότε τελειώνει ένα νήμα } }
δημόσια τάξη Στόχος { δημόσια λίστα<String> sList { get; σειρά; } δημόσιο WaitHandle WaitHandle { get; σειρά; } public int ThreadIndex { get; σειρά; }
}
|