| 
 | 
  
 
//要执行的业务是从阿里云上下载将近40000条的音频到本地,单条下载忒慢,就想采用多线程,分配了二十个线程同时下载,省了很大部分的时间 
          class Program 
    { 
 
        static void Main(string[] args) { 
            string sql = "select en_audio,us_audio from t_audio LIMIT 198 "; 
            MySqlDataReader mySqlDataReader = DBHelper.ExecuteReader(sql);          
            List<String> sList = new 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"); 
            if (mySqlDataReader.HasRows) 
            { 
                while (mySqlDataReader.Read()) 
                {                  
                    sList.Add(mySqlDataReader.GetString(0)); 
                    sList.Add(mySqlDataReader.GetString(1)); 
                } 
            }               
            Console.WriteLine(sList.Count); 
            Stopwatch stopwatch = new Stopwatch(); 
            stopwatch.Start(); 
            ThreadStart(sList); 
            WaitHandle.WaitAll(waits);  //监听wait里面的所有的线程都已经set了 才执行下面的代码,否则一直在这里等待 
            stopwatch.Stop(); 
            Console.WriteLine($"耗时{stopwatch.ElapsedMilliseconds}毫秒"); 
            Console.ReadKey(); 
 
 
        } 
       static  Thread[] threads = new Thread[20]; 
        static WaitHandle[] waits = new WaitHandle[20]; 
        public  static void ThreadStart(List<String> nums) { 
                  //分配线程 
            for (int i=0;i<20;i++) { 
                threads[i] = new Thread(DownLoadFile); 
                waits[i] = new AutoResetEvent(false); 
 
            } 
                 //为每个线程分配要执行的数据并开始执行 
            for (int i = 0; i < 20; i++) 
            { 
                if (i== threads.Length-1) { 
                    var retult = nums.Skip(nums.Count / 20 * i).Take(nums.Count- nums.Count / 20*i).ToList(); 
                    threads[i].Start(new Objpt() 
                    { 
                        sList = retult, 
                        WaitHandle = waits[i], 
                        ThreadIndex = i 
                    }); 
                } 
                else { 
                  var retult= nums.Skip(nums.Count / 20 * i).Take(nums.Count / 20).ToList(); 
                    threads[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($"线程{optObj.ThreadIndex}开始了"); 
            foreach (var url in sList) 
            { 
                try 
                { 
                    count++; 
                    var arrs = url.Split('/'); 
                    WebRequest request = WebRequest.Create(url); 
                    HttpWebResponse res = (HttpWebResponse)request.GetResponse(); 
                    WebResponse response = request.GetResponse();            
                    if (res.StatusCode.ToString() == "OK") 
                    { 
                        Stream responseStream = response.GetResponseStream(); 
                        using (FileStream fsWrite = new FileStream($"F:/Audio/v4/{arrs[arrs.Length - 2]}/{arrs[arrs.Length - 1]}", FileMode.OpenOrCreate, FileAccess.Write)) 
                        { 
                            byte[] buffer = new byte[response.ContentLength]; 
                            while (true) 
                            { 
                                ////返回本次实际读取到的字节数 
                                int r = responseStream.Read(buffer, 0, buffer.Length); 
                                if (r == 0) 
                                { 
                                    break; 
                                } 
                                fsWrite.Write(buffer, 0, r);///写入 
 
                            } 
                        } 
                    } 
                    //if (count % 20 == 0 || count == sList.Count) 
                    //{ 
                    //    Console.WriteLine($"线程{optObj.ThreadIndex}已处理个数:{count}"); 
                    //} 
 
                } 
                catch (Exception ex) 
                { 
                    string strErrorLogFile = System.AppDomain.CurrentDomain.BaseDirectory + $"\\{optObj.ThreadIndex}ErrorLog.log"; 
                    if (!System.IO.File.Exists(strErrorLogFile)) 
                        System.IO.File.WriteAllText(strErrorLogFile, "//系统错误日志记录文件\r\n"); 
                    object objSql ="线程"+ optObj.ThreadIndex.ToString()+ ex.Message; 
                    System.IO.File.AppendAllText(strErrorLogFile, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + objSql.ToString() + url + "\r\n"); 
 
                } 
 
            } 
            Console.WriteLine($"线程{optObj.ThreadIndex}结束"); 
            (optObj.WaitHandle as AutoResetEvent).Set();  //set方法是当某个线程结束起做个标记的作用 
        } 
    } 
 
     public class Objpt { 
        public List<String> sList { get; set; } 
        public WaitHandle WaitHandle { get; set; } 
        public int ThreadIndex { get; set; } 
 
    } 
 
 |   
 
上一篇:net/c# 如何实现dns劫持下一篇:DateTime的使用 
 
 |