HttpWebRequest 满足以下几点

  • 在线
  • 断点续传
  • 下载进度
  • 后台任务(未完成) 在请求之前一定要给Headers 赋值 range 范围,通知服务器从那里开始下载,打开文件从当前文件流开始写入
public async void simpleDownload(IAsyncResult asynchronousResult)
{
    long currentLength = 0L;
    long totalLength = 0L;//总大小

    HttpWebRequest myHttpWebRequest = (HttpWebRequest)asynchronousResult.AsyncState;
    // Read the response into a Stream object.
    WebResponse response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(asynchronousResult);
    totalLength = response.ContentLength;
    _param.TotalSize = totalLength+currentLength;
    NotifyStateChanged(DownloadState.Downloading, DownloadState.Preparing);

    //选择恰当的流,避免下载图片过程中僵死  
    Stream responseStream = response.GetResponseStream();
    IInputStream inputStream = responseStream.AsInputStream();
    using (var fs = await _StorageFile.OpenStreamForWriteAsync())
    {
        ulong totalBytesRead = 0;
        WeYaLog.Instance.Info("开始下载");
        currentLength = fs.Length;
        WeYaLog.Instance.Info("Range currentLength: " + currentLength.ToString());

        fs.Seek(currentLength, SeekOrigin.Current);

        DateTime now = DateTime.Now;
        StopTimer.Instance.StartRunTime();
        uint numSpeed = 0;
        uint length = 1024;//缓冲,1kb,如果设置的过大,而要下载的文件大小小于这个值,就会出现乱码。
        while (true)
        {
            // Read from the web.  
            //建立字节组,并设置它的大小是多少字节
            IBuffer buffer = new Windows.Storage.Streams.Buffer(length);
            buffer = await inputStream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None);
            numSpeed = buffer.Length;

            if (buffer.Length == 0)
            {
                WeYaLog.Instance.Info("下载完成");
                // 完成  
                NotifyStateChanged(DownloadState.Finished, DownloadState.Downloading);
                break;
            }
            // 进度  
            totalBytesRead += buffer.Length;
            double totalMilliseconds = (DateTime.Now - now).TotalMilliseconds;

            if (_cancelDownload)
            {
                WeYaLog.Instance.Info("======准备暂停===========");
                _cancelDownload = false;
                myHttpWebRequest.Abort();
                WeYaLog.Instance.Info("======暂停完成===========");
                break;
            }
            _param.DownloadSize = (long)totalBytesRead;

            if (totalMilliseconds > 100.0)
            {
                _param.Speed = (int)(numSpeed / totalMilliseconds * 1000.0);
                now = DateTime.Now;
                numSpeed = 0;
                DownloadProgress?.Invoke(this, new DownloadEventArgs(SongRid, Parameter));
            }
            numSpeed += length;

            //判断网络
            if (!DeviceUtil.IsNetworkAvailable)
            {
                NotifyStateChanged(DownloadState.NetFailed, DownloadState.Downloading);
                break;
            }
            byte[] nbtye = ConverterUtil.Buffer2Bytes(buffer);
            // 写文件.
            await fs.WriteAsync(nbtye, 0, nbtye.Length);

        }
    }

    if (inputStream != null)
        inputStream.Dispose();
}

private void BeginRequest(string URL, bool isResume)
{
    HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri(URL));
    if(isResume)
        myHttpWebRequest.Headers["Range"] = string.Format("bytes={0}-", Parameter.DownloadSize);

    myHttpWebRequest.UseDefaultCredentials = false;
    IAsyncResult result = myHttpWebRequest.BeginGetResponse(RespCallback, myHttpWebRequest);
}

另外一个实现:http://lufred.github.io/2016/05/16/Breakpoint-Continuingly