多文件上传简单实现
五一假期后的第一天上班,无聊,做了一个简单的多文件上传,如下:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using System.IO; namespace MultiFileUploadDemo { public partial class ucFileUpload : UserControl { #region 字段 private clsFTP ftp; private string _filePath; #endregion #region 构造函数 public ucFileUpload(string _filePath) { InitializeComponent(); this._filePath = _filePath; this.ftp = new clsFTP(new Uri("ftp://192.168.12.56/"), "admin", "123456"); } #endregion #region 属性 private WorkState _state = WorkState.Ready; public WorkState State { get { return _state; } set { _state = value; string msg = ""; switch (_state) { case WorkState.Ready: msg = "准备上传"; break; case WorkState.Running: msg = "开始上传"; break; case WorkState.Wait: msg = "等待上传"; break; case WorkState.Cancel: msg = "暂停上传"; break; case WorkState.Complete: msg = "上传完成"; break; default: break; } if(!this.IsHandleCreated) { IntPtr ptr = this.Handle; } this.Invoke(new Action(() => { lblUpload.Text = msg; })); } } private Action<ucFileUpload> _remove; public Action<ucFileUpload> Remove { get { return _remove; } set { _remove = value; } } #endregion #region 运行 public void Run() { ftp.UploadProgressChanged += ftp_UploadProgressChanged; ftp.UploadFileCompleted += ftp_UploadFileCompleted; ftp.UploadFileAsync(_filePath, Path.GetFileName(_filePath), true); } #endregion #region 上传进度变化 void ftp_UploadProgressChanged(object sender, System.Net.UploadProgressChangedEventArgs e) { this.Invoke(new Action(() => { progressBar1.Value = e.ProgressPercentage; lblUpload.Text = e.ProgressPercentage + "%"; })); } #endregion #region 上传完成 void ftp_UploadFileCompleted(object sender, System.Net.UploadFileCompletedEventArgs e) { State = WorkState.Complete; if (_remove != null) _remove(this); } #endregion } public enum WorkState { Ready, Running, Wait, Cancel, Complete } }

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace MultiFileUploadDemo { public partial class Form1 : Form { private List<ucFileUpload> runningList = new List<ucFileUpload>();//运行列表 private List<ucFileUpload> waitList = new List<ucFileUpload>();//等待列表 private int maxThreadNum = 2;//最大运行线程数 public Form1() { InitializeComponent(); } //Open并选择要上传的文件 private void btnOpen_Click(object sender, EventArgs e) { openFileDialog1 = new OpenFileDialog(); openFileDialog1.Multiselect = true; DialogResult dr = openFileDialog1.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { string[] files = openFileDialog1.FileNames; int s = 0; for (int i = 0; i < files.Length; i++) { ucFileUpload uc = new ucFileUpload(files[i]); uc.Top = s; s += 30; if (i >= maxThreadNum) { uc.State = WorkState.Wait; waitList.Add(uc); } else { uc.State = WorkState.Ready; runningList.Add(uc); } uc.Remove = this.Remove;//上传完成时执行 panel1.Controls.Add(uc); } } } [MethodImpl(MethodImplOptions.Synchronized)] private void Remove(ucFileUpload uc) { runningList.Remove(uc); if (waitList.Count > 0) { ucFileUpload temp = waitList.First(); temp.State = WorkState.Running; Thread t = new Thread(temp.Run); t.IsBackground = true; runningList.Add(temp); waitList.Remove(temp); t.Start(); } } //上传 private void btnUpload_Click(object sender, EventArgs e) { int index; for (int i = 0; i < maxThreadNum; i++) { index = i; Thread t = new Thread(runningList[index].Run); t.IsBackground = true; t.Start(); } } } }
效果如下:
其中,ClsFTP类是某位园友封装的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)