zoukankan      html  css  js  c++  java
  • 多线程上传

    上传公共类

    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
    委托类与上传状态枚举
  • 相关阅读:
    WPF入门教程系列六——布局介绍与Canvas(一)
    WPF入门教程系列五——Window 介绍
    WPF入门教程系列四——Dispatcher介绍
    WPF入门教程系列三——Application介绍(续)
    html5 标签
    html5
    sublime汉化教程
    html5 文本格式化
    主键和索引的区别
    响应式布局的开发基础知识
  • 原文地址:https://www.cnblogs.com/hyxf/p/5409889.html
Copyright © 2011-2022 走看看