HTTP206 status code and C # implementation of multi-threaded download Demo
Basic knowledge
HTTP206 status code
Multithreading technology
Implementation of Multithread Download
thinking
-
If it is supported, initialize the thread pool, build the number of threads set by the user, calculate the starting and ending points of the file stream that each thread needs to be responsible for, initialize the thread to start downloading, and merge the files downloaded by each thread according to the download log after all downloads are completed. -
If not, initialize a thread and download the corresponding file.
Programming
-
SingleThreadDownloader: single thread download class, including a thread reference, initialization method, etc. -
MTDController: Multi thread download control class, including a single thread linked list, initialization method, allocation method, etc.
Important code
Thread running parameter class:
class MTDThreadInfo { public HttpWebRequest MTDRequest { get; set; } public string MTDFileName { get; set; } public long MTDFileSize { get; set; } public string MTDFilePath { get; internal set; } }
Single thread download class:
class SingleThreadDownoad{ float progress = 0; private Thread mThread; private HttpWebRequest mRequest; private MTDThreadInfo mMtdThreadInfo; public void StartDownLoad() { //Pass download parameters and start asynchronous execution thread mThread.Start(mMtdThreadInfo); } public void Start(object mtdInfo) { string sb; MTDThreadInfo mMTDInfo = mtdInfo as MTDThreadInfo; if (mMTDInfo == null) { //Incoming parameter error return; } HttpWebRequest tRequest = mMTDInfo.MTDRequest; //Set Save Path sb = mMTDInfo.MTDFilePath; //Get the length of accepted content long fileSize = tRequest.GetResponse(). ContentLength; if (fileSize > 0) { //TODO writes the segmentation information of the log module file //Create download file FileStream fs = File.Open(sb.ToString(), FileMode.Create); byte[] mByte = new byte[512]; //Get return stream using (Stream bs = tRequest. GetResponse(). GetResponseStream()) { int nreadsize = bs.Read(mByte, 0, 512); while (nreadsize > 0) { fs.Write(mByte, 0, nreadsize); fs.Flush(); nreadsize = bs.Read(mByte, 0, 512); } fs.Close(); bs.Close(); //TODO notification completion tRequest.Abort(); } } } public void Init(string url, string fileName, long start = 0, long end = 0) { //Create HTTP request mRequest = WebRequest.Create(url) as HttpWebRequest; mRequest.Referer = url; //Add Header if (end != 0) { mRequest.AddRange(start, end); } //Set thread information class parameters mMtdThreadInfo = new MTDThreadInfo(); mMtdThreadInfo.MTDRequest = mRequest; mMtdThreadInfo.MTDFileSize = end - start; mMtdThreadInfo.MTDFileName = fileName; mMtdThreadInfo.MTDFilePath = MTDCommonData.IOPath.savePath + fileName; //Thread creates parameter to execute Start method ParameterizedThreadStart parameterStart = new ParameterizedThreadStart(Start); //Create Thread mThread = new Thread(parameterStart); } public float GetProgress() { //TODO View Layer Refresh return this.progress; } public void Destroy() { //Thread stops running //TODO subsequent processing mThread.Abort(); } }
Multi thread download control class key code
/// <summary> ///Initialize threads and allocate segmented tasks /// </summary> /// <param name="threadNum"></param> public void InitThread(int threadNum) { //Size Index long fileSizeIndex = 0; //Last remaining size long lastSize = mFileSize % threadNum; //Average size long avgSize = mFileSize / threadNum; //TODO judges that the server does not support segmented downloading for (int i = 0; i < threadNum; i++) { //Initialize each thread if (i == (threadNum - 1) ) { //Last thread mThreads[i]. Init(mFileUrl, mFileName + "_" + i, fileSizeIndex, mFileSize - 1); //The TODO log module records the following information Sw.WriteLine ("[{3}] Thread {0}: {1} bytes - {2} bytes, start execution", i, fileSizeIndex, mFileSize - 1, DateTime.Now); sw.Flush(); break; } mThreads[i]. Init(mFileUrl, mFileName + "_" + i, fileSizeIndex, (fileSizeIndex + avgSize - 1)); //The TODO log module records the following information Sw.WriteLine ("[{3}] Thread {0}: {1} bytes - {2} bytes, start execution", i,fileSizeIndex,fileSizeIndex + avgSize - 1, DateTime.Now); sw.Flush(); fileSizeIndex += avgSize; } sw.Close(); fs.Close(); for (int i = 0; i < threadNum; i++) { //Start execution thread mThreads[i]. StartDownLoad(); } //TODO updates the View according to the corresponding value //Merge files after TODO } /// <summary> ///Add a download thread /// </summary> /// <param name="url"></param> /// <param name="fileName"></param> /// <param name="filePath"></param> /// <param name="start"></param> /// <param name="end"></param> public void InitThread(string url, string fileName,long start,long end) { SingleThreadDownoad st = new SingleThreadDownoad(); st.Init(url, fileName ,start, end); mThreads.Add(st); }
Other key points
-
C # The default maximum number of threads for HttpWebRequest is 2. Use the following code to modify the maximum number of connections ServicePointManager.DefaultConnectionLimit = 10; -
Note the TODO work list in the article -
Pay attention to completing MTDcontroller
Operation results
MTDController mtdCtrl = new MTDController(); mtdCtrl.Init("//[url]/desktop/bg/acg/58102922_p0.jpg", 4); mtdCtrl.StartDownload();
References
Comment
Comment area
0F Passing by with a confused face 0F Surprise a white scholar, kill him or her (# funny) 0F Emmm, you are so diligent. I feel that my blog is in labor! Ha ha ha 0F The blogger is a female blogger~ Yes, she is cute.
0F Scared, looking at the good code, the URL of his website suddenly appeared (insidious) U • ェ * U yawn~
0F Picture taken away~ 0F You may not believe it. The screenshot is proof that you have been targeted 🙂 ! [miao.gif]( https://view.moezx.cc/images/2018/03/20/miao.gif ) Jump to the Ministry of Public Security without providing the get parameter... better than nothing