// 开始一个下载任务
        private void StartTask(DownloadInfo taskinfo)
        {
            if (this.m_DownloadingTasks.ContainsKey(taskinfo.fileName))
            {
                DebugUtil.Log("task already in progress :{0}", taskinfo.fileName);
            }
            else
            {
                DownloadingTask value = new DownloadingTask(taskinfo);
                this.m_DownloadingTasks[taskinfo.fileName] = value;

                if (!File.Exists(taskinfo.tempPath))
                {
                    FilePathTools.CreateFolderByFilePath(taskinfo.tempPath);
                    File.Create(taskinfo.tempPath).Dispose();
                }

                using (var sw = new FileStream(taskinfo.tempPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    taskinfo.downloadedSize = (int)sw.Length;
                }

                HttpDownload(value);
            }
        }
        public void AbortDownloadTask(DownloadingTask task)
        {
            if (task != null)
            {
                HTTPRequest headRequest = task.HeadRequest;
                if (headRequest != null)
                {
                    long headstarttime = DragonU3DSDK.Utils.TotalMilliseconds();
                    EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(task.DownloadInfo.fileName, "head_abort", 0, task.DownloadInfo.retry.ToString()).Trigger();
                    long headbistarttime = DragonU3DSDK.Utils.TotalMilliseconds();
                    headRequest.Abort();
                    long headaborttime = DragonU3DSDK.Utils.TotalMilliseconds();

                    //DebugUtil.LogError("Download Downloading loop {0} headBI is {1} headAbort is {2}", i, (headbistarttime - headstarttime), (headaborttime - headbistarttime));
                }
                if (task.Downloader != null)
                {
                    long taskstarttime = DragonU3DSDK.Utils.TotalMilliseconds();
                    EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(task.DownloadInfo.fileName, "abort", task.DownloadInfo.downloadedSize, task.DownloadInfo.retry.ToString()).Trigger();
                    long taskbistarttime = DragonU3DSDK.Utils.TotalMilliseconds();
                    task.Downloader.CancelDownload(false);
                    long tastaborttime = DragonU3DSDK.Utils.TotalMilliseconds();

                    //DebugUtil.LogError("Download Downloading loop {0} taskBI is {1} headAbort is {2}", i, (taskbistarttime - taskstarttime), (tastaborttime - taskbistarttime));
                }
                task.DownloadInfo.isFinished = true;
                task.DownloadInfo.retry      = 0;//保证不会再被添加到下载队列里了
            }
        }
        static void DownloadCommonInitialABWithBreakDownloader(BaseResFakeInfo rrInfo)
        {
            DownloadInfo taskinfo = new DownloadInfo(rrInfo.LocalABPath, rrInfo.GetPlatformMd5(), null);

            taskinfo.savePath = FilePathTools.streamingAssetsPath_Platform + "/" + rrInfo.LocalABPath.ToLower();
            if (File.Exists(taskinfo.savePath))
            {
                File.Delete(taskinfo.savePath);
            }

            FilePathTools.CreateFolderByFilePath(taskinfo.savePath);

            if (!File.Exists(taskinfo.tempPath))
            {
                FilePathTools.CreateFolderByFilePath(taskinfo.tempPath);
                File.Create(taskinfo.tempPath).Dispose();
            }

            using (var sw = new FileStream(taskinfo.tempPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                taskinfo.downloadedSize = (int)sw.Length;
            }

            DownloadingTask tmpTask     = new DownloadingTask(taskinfo);
            HTTPRequest     httprequest = new HTTPRequest(new Uri(tmpTask.DownloadInfo.url), HTTPMethods.Head, (req, rep) =>
            {
                tmpTask.HeadRequest = null;
                if (rep == null)
                {
                    CommonResLog("Download failed due to network for :{0}", tmpTask.DownloadInfo.fileName);
                    tmpTask.DownloadInfo.result = DownloadResult.ServerUnreachable;
                    DownloadCommonInitialABWithBreakDownloader(rrInfo);
                }
                else if (rep.StatusCode == 200)
                {
                    try
                    {
                        string firstHeaderValue           = rep.GetFirstHeaderValue("Content-Length");
                        tmpTask.DownloadInfo.downloadSize = int.Parse(firstHeaderValue);
                        CommonResLog("Will download {0} bytes for  '{1}'", tmpTask.DownloadInfo.downloadSize, tmpTask.DownloadInfo.fileName);
                        BreakPointDownloader downloader = new BreakPointDownloader(tmpTask.DownloadInfo, new Dictionary <string, DownloadingTask>());
                        tmpTask.Downloader = downloader;
                        downloader.StartDownload();
                    }
                    catch (Exception ex)
                    {
                        CommonResLog("An error occured during download '{0}' due to {1}", tmpTask.DownloadInfo.fileName, ex);
                        tmpTask.DownloadInfo.result = DownloadResult.Failed;
                        DownloadCommonInitialABWithBreakDownloader(rrInfo);
                    }
                }
                else
                {
                    CommonResLog("Response is not ok! for: {0}", tmpTask.DownloadInfo.url);
                    tmpTask.DownloadInfo.result = DownloadResult.Failed;
                    DownloadCommonInitialABWithBreakDownloader(rrInfo);
                }
            })
            {
                DisableCache = true
            };

            httprequest.Send();
        }
        // 新建下载器开始下载
        private void HttpDownload(DownloadingTask task)
        {
            DebugUtil.Log("Start Download:{0}", task.DownloadInfo.fileName);

            DownloadingTask tmpTask     = task;
            HTTPRequest     httprequest = new HTTPRequest(new Uri(tmpTask.DownloadInfo.url), HTTPMethods.Head, (req, rep) =>
            {
                switch (req.State)
                {
                case HTTPRequestStates.ConnectionTimedOut:
                case HTTPRequestStates.TimedOut:
                    EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(tmpTask.DownloadInfo.fileName, "head_timeout", 0, tmpTask.DownloadInfo.retry.ToString()).Trigger();
                    break;

                case HTTPRequestStates.Aborted:
                    EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(tmpTask.DownloadInfo.fileName, "head_abort", 0, tmpTask.DownloadInfo.retry.ToString()).Trigger();
                    break;

                case HTTPRequestStates.Error:
                    EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(tmpTask.DownloadInfo.fileName, "head_failure", 0, tmpTask.DownloadInfo.retry.ToString()).Trigger();
                    break;

                case HTTPRequestStates.Finished:
                    if (rep != null && rep.StatusCode >= 200 && rep.StatusCode < 400)
                    {
                        EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(tmpTask.DownloadInfo.fileName, "head_finish", 0, tmpTask.DownloadInfo.retry.ToString()).Trigger();
                    }
                    else
                    {
                        EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(tmpTask.DownloadInfo.fileName, "head_failure", 0, tmpTask.DownloadInfo.retry.ToString()).Trigger();
                    }
                    break;
                }

                if (!this.m_DownloadingTasks.ContainsKey(tmpTask.DownloadInfo.fileName))
                {
                    DebugUtil.Log("Cancelled Task :{0}", tmpTask.DownloadInfo.fileName);
                    return;
                }

                tmpTask.HeadRequest = null;
                if (rep == null)
                {
                    DebugUtil.LogError("Download failed due to network for :{0}", tmpTask.DownloadInfo.fileName);
                    tmpTask.DownloadInfo.result = DownloadResult.ServerUnreachable;
                    RetryDownload(tmpTask.DownloadInfo);
                }
                else if (rep.StatusCode == 200 || rep.StatusCode == 206)
                {
                    try
                    {
                        string firstHeaderValue           = rep.GetFirstHeaderValue("Content-Length");
                        tmpTask.DownloadInfo.downloadSize = int.Parse(firstHeaderValue);
                        DebugUtil.Log("Will download {0} bytes for  '{1}'", tmpTask.DownloadInfo.downloadSize, tmpTask.DownloadInfo.fileName);
                        BreakPointDownloader downloader = new BreakPointDownloader(tmpTask.DownloadInfo, this.m_DownloadingTasks);
                        tmpTask.Downloader = downloader;
                        downloader.StartDownload();
                    }
                    catch (Exception ex)
                    {
                        DebugUtil.LogError("An error occured during download '{0}' due to {1}", tmpTask.DownloadInfo.fileName, ex);
                        tmpTask.DownloadInfo.result = DownloadResult.Failed;
                        RetryDownload(tmpTask.DownloadInfo);
                    }
                }
                else
                {
                    DebugUtil.Log("statecode = {0}.Response is not ok! for: {1}", rep.StatusCode, tmpTask.DownloadInfo.url);
                    tmpTask.DownloadInfo.result = DownloadResult.Failed;
                    RetryDownload(tmpTask.DownloadInfo);
                }
            })
            {
                DisableCache = true
            };

            this.m_DownloadingTasks[tmpTask.DownloadInfo.fileName].HeadRequest = httprequest;
            EventManager.Instance.Trigger <SDKEvents.DownloadFileEvent>().Data(tmpTask.DownloadInfo.fileName, "head_start", 0, tmpTask.DownloadInfo.retry.ToString()).Trigger();
            httprequest.Send();
        }