private void DownloadPart()

in sdk/Common/ResumableDownloadManager.cs [362:445]


        private void DownloadPart(object state)
        {
            DownloadTaskParam taskParam = state as DownloadTaskParam;
            if (taskParam == null)
            {
                throw new ClientException("Internal error. The taskParam should be type of DownloadTaskParam");
            }
            DownloadObjectRequest request = taskParam.Request;
            ResumablePartContext part = taskParam.Part;
            EventHandler<StreamTransferProgressArgs> downloadProgressCallback = taskParam.DownloadProgressCallback;

            try
            {
                string fileName = GetTempDownloadFile(request); 
                if (part.IsCompleted && File.Exists(fileName))
                {
                    // is CRC is enabled and part.Crc64 is 0, then redownload the data
                    if (!_conf.EnableCrcCheck || part.Crc64 != 0)
                    {
                        return;
                    }
                }

                const int retryCount = 3;
                for (int i = 0; i < retryCount; i++)
                {
                    try
                    {
                        GetObjectRequest partRequest = request.ToGetObjectRequest();
                        partRequest.SetRange(part.Position, part.Position + part.Length - 1);
                        using(var partResult = _ossClient.GetObject(partRequest))
                        {
                            Crc64Stream crcStream = null;
                            if (_conf.EnableCrcCheck)
                            {
                                crcStream = new Crc64Stream(partResult.Content, null, part.Length, 0);
                            }

                            using(var fs = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                            {
                                fs.Seek(part.Position, SeekOrigin.Begin);

                                long totalBytes = WriteTo(crcStream ?? partResult.Content, fs);
                                if (totalBytes != part.Length)
                                {
                                    throw new OssException(string.Format("Part {0} returns {1} bytes. Expected size is {2} bytes", 
                                                           part.PartId, totalBytes, part.Length));
                                }
                                Interlocked.Add(ref _downloadedBytes, partResult.ContentLength);
                            }

                            part.IsCompleted = true;
                            if (crcStream != null)
                            {
                                if (crcStream.CalculatedHash == null)
                                {
                                    crcStream.CalculateHash();
                                }
                                part.Crc64 = BitConverter.ToUInt64(crcStream.CalculatedHash, 0);
                            }

                            return;
                        }
                    }
                    catch (Exception ex) // when the connection is closed while sending the data, it will run into ObjectDisposedException.
                    {
                        if (!(ex is ObjectDisposedException || ex is WebException) || i == retryCount - 1)
                        {
                            throw;
                        }
                    }
                }

                throw new ClientException("DownloadPart runs into internal error");
            }
            catch(Exception e)
            {
                taskParam.Error = e;
            }
            finally
            {
                taskParam.DownloadFinished.Set();
            }
        }