多线程上传

上传公共类

public class UploadFile
    {
        #region 变量
        /// <summary>
        /// 起始位置
        /// </summary>
        long Begin;
        /// <summary>
        /// 结束位置
        /// </summary>
        long End;
        /// <summary>
        /// 每次上传的容量
        /// </summary>
        long size;

        /// <summary>
        /// 下载文件的大小
        /// </summary>
        public long FileSize;
        
        public string FileUrl;

        /// <summary>
        /// 是否暂停线程
        /// </summary>
        bool isRunning = true;

        //下载状态
        private UploadStatus status;

        /// <summary>
        /// 每次下载容量
        /// </summary>
        long DownloadCapacity;

        /// <summary>
        /// 下载已耗时
        /// </summary>
        private TimeSpan useTime;

        /// <summary>
        /// 最后一次下载时间
        /// </summary>
        private DateTime lastStartTime;

        /// <summary>
        /// 预计下载总耗时
        /// </summary>
        private TimeSpan allTime;

        /// <summary>
        /// 上一秒时已下载总大小
        /// </summary>
        private long BeforSecondUploadSize;

        /// <summary>
        /// 已下载大小
        /// </summary>
        private long UploadSize = 0;

        /// <summary>
        /// 当前下载速度
        /// </summary>
        private double speed;
        /// <summary>
        /// 是否上传完毕
        /// </summary>
        bool iscomplete = false;

        System.Timers.Timer t = new System.Timers.Timer();

        Task task;
        CancellationTokenSource cancelTokenSource = new CancellationTokenSource();

        public string parentFolderId { get; set; }
        /// <summary>
        /// 任务ID
        /// </summary>
        public string taskID { get; set; }
        /// <summary>
        /// 任务文档ID
        /// </summary>
        public string taskDocId { get; set; }
        /// <summary>
        /// 通用文档树文件夹ID
        /// </summary>
        public string folderId { get; set; }
        /// <summary>
        /// 通用文档根节点ID(第一级目录)
        /// </summary>
        public string docListId { get; set; }
        /// <summary>
        /// 上传或者更新文件类型,0为:作业文档;1为:通用文档;2为:问题文档;3为:工作流文档
        /// </summary>
        public int docType { get; set; }
        /// <summary>
        /// 上传类型,0为:上传;1为:更新
        /// </summary>
        public int opType { get; set; }

        UplpadDetectionFileDto detectionDto = new UplpadDetectionFileDto();
        #endregion

        #region 启动上传
        /// <summary>
        /// 启动上传
        /// </summary>
        /// <param name="UploadUrl">上传的URL</param>
        /// <param name="DetectionUrl">检测文件的URL</param>
        public void Startup(string UploadUrl, string DetectionUrl, UplpadDetectionFileDto DetectionDto)
        {
            if (this.status == UploadStatus.Idle)
            {
                MessageUtil.ShowError("只有空闲中才能上传!");
                return;
            }

            UplpadDetection Detection = WebCommunication.JsonRequestServiceToObject<UplpadDetection>(DetectionUrl, DetectionDto, CommonInfo.Ticike);
            if (Detection.rsCode == "S10000")
            {
                if (Detection.Isexist == true)
                {
                    Begin = Detection.StartingValue;
                }
                else
                {
                    Begin = 0;
                }
            }
            else
            {
                MessageUtil.ShowError(ExceptionCode.GetCodeByExceptionInfo(Detection.rsCode));
            }

            t.Interval = 1000;
            t.Elapsed -= new System.Timers.ElapsedEventHandler(t_Elapsed);
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
            t.Start();
            detectionDto = DetectionDto;
            BeginUpload(UploadUrl, DetectionDto.FileGuid, DetectionDto.ActiomId, DetectionDto.FileName);
        }

        void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            OnUpload();

            if (iscomplete)
            {
                isRunning = false;
                t.Elapsed -= new System.Timers.ElapsedEventHandler(t_Elapsed);
                t.Enabled = false;
                //t.Close();
                UploadSuccessDto Successdto = new UploadSuccessDto();
                Successdto.fileGuid = detectionDto.FileGuid;
                Successdto.fileName = detectionDto.FileName;
                Successdto.proj_id = CommonInfo.ProjectId;
                Successdto.taskID = taskID;
                Successdto.taskDocId = taskDocId;
                Successdto.parentFolderId = parentFolderId;
                Successdto.folderId = folderId;
                Successdto.docListId = docListId;
                Successdto.docType = docType;
                Successdto.opType = opType;
                Successdto.userId = CommonInfo.UserGrid;

                string successUrl = BaseClass.GetUrl("Upload", "UploadSuccess");
                BaseDto dto = WebCommunication.JsonRequestServiceToObject<BaseDto>(successUrl, Successdto, CommonInfo.Ticike);
                if (dto.rsCode == "S10000")
                {
                    string sql = "UPDATE DownloadFileLocally set IsSuccess=1 where ActiomId='" + detectionDto.ActiomId + "'";
                    if (SQLiteOperation.UpdataSQlite(sql, null) > 0)
                    {
                        DownloadFileService.UpdateFileListComplete(detectionDto.ActiomId);
                        t.Elapsed -= new System.Timers.ElapsedEventHandler(t_Elapsed);
                        uploadComplete(true, "UploadComplete", detectionDto.FileGuid);
                        return;
                    }
                }
                else
                {
                    string errorinfo=ExceptionCode.GetCodeByExceptionInfo(dto.rsCode);
                    MessageUtil.ShowError(detectionDto.FileName + ":" + errorinfo);
                    string sql = "UPDATE DownloadFileLocally set IsSuccess=2,ErrorInfo='" + errorinfo + "' where ActiomId='" + detectionDto.ActiomId + "'";
                    SQLiteOperation.UpdataSQlite(sql, null);
                    t.Elapsed -= new System.Timers.ElapsedEventHandler(t_Elapsed);
                    uploadComplete(true, "UploadComplete", detectionDto.FileGuid);
                    return;
                }
            }
            //else { 
            //    if(Begin <= End)
            //}
        } 
        #endregion

        #region 上传暂停
        /// <summary>
        /// 上传暂停
        /// </summary>
        public void Pause()
        {
            if (this.status != UploadStatus.Uploading)
            {
                MessageUtil.ShowError("只有上传中才能暂停!");
                return;
            }

            // 后台线程会查看状态,如果状态时暂停的,
            // 下载将会被暂停并且状态将随之改为暂停.
            this.status = UploadStatus.Pausing;

            isRunning = false;
        } 
        #endregion

        #region 继续上传
        /// <summary>
        /// 继续上传
        /// </summary>
        public void Continue()
        {
            if (this.status != UploadStatus.Pausing)
            {
                MessageUtil.ShowError("只有暂停状态才能继续上传!");
                return;
            }
            this.status = UploadStatus.Uploading;

            isRunning = true;
        } 
        #endregion

        #region 取消上传
        ///<summary>
        ///取消上传
        ///</summary>
        public void Cancel(string FileGuid, string Uploadurl, string ActiomId, string FileName)
        {
            this.status = UploadStatus.Cancel;
            cancelTokenSource.Cancel();
            isRunning = false;
            size = DownloadCapacity * 1024;
            End = FileSize;
            UploadMethod(Uploadurl, DownloadCapacity, FileGuid, ActiomId, FileName, size, End,false);


        } 
        #endregion

        /// <summary>
        /// 重新上传
        /// </summary>
        public void Again(string UploadUrl, string DetectionUrl, UplpadDetectionFileDto DetectionDto)
        {
            this.status = UploadStatus.Cancel;
            cancelTokenSource.Cancel();
            isRunning = false;
            size = DownloadCapacity * 1024;
            End = FileSize;
            UploadMethod(UploadUrl, DownloadCapacity, DetectionDto.FileGuid, DetectionDto.ActiomId, DetectionDto.FileName, size, End, false);

            status = UploadStatus.Uploading;
            UplpadDetection Detection = WebCommunication.JsonRequestServiceToObject<UplpadDetection>(DetectionUrl, DetectionDto, CommonInfo.Ticike);
            if (Detection.rsCode == "S10000")
            {
                if (Detection.Isexist == true)
                {
                    Begin = Detection.StartingValue;
                }
                else
                {
                    Begin = 0;
                }
            }
            else
            {
                MessageUtil.ShowError(ExceptionCode.GetCodeByExceptionInfo(Detection.rsCode));
            }

            t.Interval = 1000;
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
            t.Start();
            detectionDto = DetectionDto;
            BeginUpload(UploadUrl, DetectionDto.FileGuid, DetectionDto.ActiomId, DetectionDto.FileName);
        }

        #region 上传方法
        /// <summary>
        /// 多线程上传
        /// </summary>
        /// <param name="UploadUrl">上传URL</param>
        /// <param name="FileGuid">文件Guid</param>
        private void BeginUpload(string UploadUrl,string FileGuid,string ActiomId,string FileName)
        {
            try
            {
                //获取线程数
                EPMSDto.LocalData.DownloadConfiguration configuration = LocalDataDownloadConfiguration.GetDownloadConfigurationByUserName(CommonInfo.LoginName);
                DownloadCapacity = configuration.DownloadCapacity;
                ////计算出单次下载量
                size = DownloadCapacity * 1024;
                End = FileSize;
                bool complete = false;

                //遍历线程数(遍历几次就是启动几个线程)
                //for (int i = 0; i < configuration.ThreadNum; i++)
                //{
                    task = Task.Factory.StartNew(() => UploadMethod(UploadUrl, DownloadCapacity, FileGuid, ActiomId, FileName, size, End, complete), cancelTokenSource.Token);
                //    Random rd = new Random();
                //    int num= rd.Next(1500,2000);
                //    Thread.Sleep(num);
                //}

                //UploadMethod(UploadUrl, DownloadCapacity, FileGuid, ActiomId, FileName);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(typeof(DownLoadFile), ex);
            }
        }

        /// <summary>
        /// 上传方法
        /// </summary>
        /// <param name="Uploadurl">上传的路径</param>
        /// <param name="DownloadCapacity">每次上传的大小(用户设置的)</param>
        /// <param name="startingValue"></param>
        public void UploadMethod(string Uploadurl, long DownloadCapacity, string FileGuid, string ActiomId, string FileName, long size, long End, bool complete)
        {
            //if (status != UploadStatus.Uploading)
            //{
            //    return;
            //}
            if (status == UploadStatus.Cancel)
            {
                t.Elapsed -= new System.Timers.ElapsedEventHandler(t_Elapsed);
                string deletesql = "delete from DownloadFileLocally where ActiomId='" + ActiomId + "'";
                if (SQLiteOperation.UpdataSQlite(deletesql, null) == 0)
                {
                    MessageUtil.ShowError("删除上传成功的文件记录出错!");
                }
                DownloadFileService.DeleteFileList(ActiomId);

                WhereDto dt = new WhereDto();
                dt.Where = FileGuid;
                string deleteurl = BaseClass.GetUrl("Upload", "CancelUpload");
                BaseDto dto = WebCommunication.JsonRequestServiceToObject<BaseDto>(deleteurl, dt, CommonInfo.Ticike);

                uploadComplete(true, "UploadCancel", FileGuid);
                return;
            }
            
            while (End > Begin)
            {
                if (Begin < End)
                {
                    if (!cancelTokenSource.IsCancellationRequested)
                    {
                        //下载保护
                        if (End - Begin < size)
                        {
                            size = End - Begin;
                            if (size < 0)
                            {
                                size = 0;
                            }
                            //上传完成在这里写
                            //iscomplete = true;
                            complete = true;
                        }

                        #region 上传
                        SpinWait.SpinUntil(() => isRunning);
                        MyUploadFileDto Filedto = new MyUploadFileDto();
                        BeforSecondUploadSize = size;
                        UploadSize = Begin;
                        //文件信息
                        System.IO.FileStream readFs = new System.IO.FileStream(FileUrl, System.IO.FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
                        long lenth = readFs.Length;
                        readFs.Position = Begin;
                        byte[] filesize = new byte[size];
                        readFs.Read(filesize, 0, Convert.ToInt32(size));
                        readFs.Close();
                        //MD5加密
                        Filedto.FileMD5 = PasswordEncrypt.getMD5Hash(filesize);
                        Filedto.ByteInfo = filesize;
                        Filedto.StartingValue = Begin;
                        Filedto.Uploadsize = size;
                        Filedto.Guid = FileGuid;

                        BaseDto dto = WebCommunication.JsonRequestServiceToObject<BaseDto>(Uploadurl, Filedto, CommonInfo.Ticike);
                        if (dto.rsCode != "S10000")
                        {
                            MessageUtil.ShowError(ExceptionCode.GetCodeByExceptionInfo(dto.rsCode));
                            string sql = "UPDATE DownloadFileLocally set IsSuccess=2,ErrorInfo='" + ExceptionCode.GetCodeByExceptionInfo(dto.rsCode) + "' where ActiomId='" + ActiomId + "'";
                            SQLiteOperation.UpdataSQlite(sql, null);
                            uploadComplete(true, "UploadCancel", FileGuid);
                            return;
                        }
                        iscomplete = complete;
                        #endregion

                    }
                }
                else {
                    iscomplete = complete;
                }
                Begin += size;
            }
            if (End <= Begin)
            {
                iscomplete = true;
            }
        } 
        #endregion

        #region 每秒信息事件方法
        /// <summary>
        /// 更新下载所用时间
        /// </summary>
        private void ChangeTime()
        {
            if (this.status == UploadStatus.Uploading)
            {
                DateTime now = DateTime.Now;
                if (now != lastStartTime)
                {
                    useTime = useTime.Add(now - lastStartTime);
                    lastStartTime = now;
                }
            }
        }

        public event UploadEventArgs.SecondUploadEventHandler SecondUploadEvent;
        /// <summary>
        /// 每秒信息方法
        /// </summary>
        public void OnUpload()
        {
            if (SecondUploadEvent != null)
            {
                ChangeTime();
                this.speed = (UploadSize - BeforSecondUploadSize) / 1024;
                long temp = 0;

                this.allTime = new TimeSpan(temp);
                int downLoadProportion = 0;
                if (UploadSize > 0)
                {
                    downLoadProportion = Convert.ToInt32((Convert.ToDecimal(UploadSize) / Convert.ToDecimal(FileSize)) * 100);
                }
                else
                {
                    downLoadProportion = 0;
                }
                UploadEventArgs.SecondUploadEventArgs e = new UploadEventArgs.SecondUploadEventArgs(UploadSize / 1024, useTime, allTime, speed, FileSize / 1024, downLoadProportion);
                SecondUploadEvent(this, e);
            }
        } 
        #endregion

        #region 上传完成的事件方法
        public event UploadEventArgs.UploadCompletedEventHandler UploadCompletedEvent;
        /// <summary>
        /// 上传完成的方法
        /// </summary>
        /// <param name="isCompleted"></param>
        /// <param name="state"></param>
        /// <param name="Guid"></param>
        public void uploadComplete(bool isCompleted, string state, string Guid)
        {
            if (UploadCompletedEvent != null)
            {
                UploadEventArgs.UploadCompletedEvent e = new UploadEventArgs.UploadCompletedEvent(isCompleted, state, Guid);
                UploadCompletedEvent(this, e);
            }
        } 
        #endregion
    }
上传公共类

上传委托类

#region 委托类
    public class UploadEventArgs
    {
        /// <summary>
        ///  与每秒下载情况相关的委托
        /// </summary>
        /// <param name="sender">事件发起的对象</param>
        /// <param name="e">参数</param>
        public delegate void SecondUploadEventHandler(Object sender, SecondUploadEventArgs e);
        /// <summary>
        /// 下载完成的委托
        /// </summary>
        /// <param name="sender">事件发起的对象</param>
        /// <param name="e">参数</param>
        public delegate void UploadCompletedEventHandler(Object sender, UploadCompletedEvent e);

        /// <summary>
        /// 下载时每秒事件相关的参数
        /// </summary>
        public class SecondUploadEventArgs : EventArgs
        {
            /// <summary>
            /// 已下载大小
            /// </summary>
            public readonly long uploadSize;

            /// <summary>
            /// 下载已耗时
            /// </summary>
            public readonly TimeSpan useTime;

            //预计下载总耗时
            public readonly TimeSpan allTime;

            /// <summary>
            /// 当前下载速度
            /// </summary>
            public readonly double speed;

            /// <summary>
            /// 文件总大小
            /// </summary>
            public readonly long fileSize;
            /// <summary>
            /// 上传比例
            /// </summary>
            public readonly int uploadProportion;

            public SecondUploadEventArgs(long uploadSize, TimeSpan useTime, TimeSpan allTime, double speed, long fileSize, int uploadproportion)
            {
                this.uploadSize = uploadSize;
                this.useTime = useTime;
                this.allTime = allTime;
                this.speed = speed;
                this.fileSize = fileSize;
                uploadProportion = uploadproportion;
            }
        }

        /// <summary>
        /// 上传完成的
        /// </summary>
        public class UploadCompletedEvent : EventArgs
        {
            /// <summary>
            /// 是否完成
            /// </summary>
            public readonly bool UploadComplete;
            /// <summary>
            /// 上传状态
            /// </summary>
            public readonly string UploadState;

            public readonly string FileGuid;
            public UploadCompletedEvent(bool isComplete, string state, string Guid)
            {
                UploadComplete = isComplete;
                UploadState = state;
                FileGuid = Guid;
            }
        }

    } 
    #endregion

    #region 上传状态枚举
    public enum UploadStatus
    {
        /// <summary>
        /// 下载
        /// </summary>
        Uploading,
        /// <summary>
        /// 
        /// </summary>
        Pausing,
        /// <summary>
        /// 空线
        /// </summary>
        Idle,
        /// <summary>
        /// 取消
        /// </summary>
        Cancel,
        /// <summary>
        /// 重新下载
        /// </summary>
        ReDownload,
        /// <summary>
        /// 完成下载
        /// </summary>
        Complete
    } 
    #endregion
委托类与上传状态枚举
原文地址:https://www.cnblogs.com/hyxf/p/5409889.html