借助WebService实现多线程上传文件

C# 通过WebService上传视频文件到服务器虚拟机下源码 请参考:http://blog.youkuaiyun.com/dwj901125/article/details/23701063 这里有相当详尽的实现过程。 立即下载

在WebService的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础上进行扩展。

 

首先说说服务器端,只需要提供一个能允许多线程写文件的函数即可,具体代码如下。

[WebMethod]

public bool UploadFileData( string FileName, int StartPosition, byte[] bData )

{

    string strFullName = Server.MapPath( "Uploads" ) + @"/" + FileName;

    FileStream fs = null;

    try

    {

        fs = new FileStream( strFullName, FileMode.OpenOrCreate,

            FileAccess.Write, FileShare.Write );

    }

    catch( IOException err )

    {

        Session["ErrorMessage"] = err.Message;

        return false;

    }

 

    using( fs )

    {

        fs.Position = StartPosition;

        fs.Write( bData, 0, bData.Length );

    }

    return true;

}

 

其中“Uploads”是在服务程序所在目录下的一个子目录,需要设置ASPNET用户对此目录具有可写权限。

 

相对于服务器端来说,客户端要稍微复杂一些,因为要牵扯到多线程的问题。为了更好的传递参数,我用一个线程类来完成。具体如下。

    public delegate void UploadFileData( string FileName, int StartPos, byte[] bData );

 

    /// <summary>

    /// FileThread: a class for sub-thread

    /// </summary>

    sealed class FileThread

    {

        private int nStartPos;

        private int nTotalBytes;

        private string strFileName;

        public static UploadFileData UploadHandle;

 

        /// <summary>

        /// Constructor

        /// </summary>

        /// <param name="StartPos"></param>

        /// <param name="TotalBytes"></param>

        /// <param name="FileName"></param>

        public FileThread( int StartPos, int TotalBytes, string FileName )

        {

            //Init thread variant

            nStartPos = StartPos;

            nTotalBytes = TotalBytes;

            strFileName = FileName;

 

            //Only for debug

            Debug.WriteLine( string.Format( "File name:{0} position: {1} total byte:{2}",

                strFileName, nStartPos, nTotalBytes ) );

        }

 

        /// <summary>

        /// Sub-thread entry function

        /// </summary>

        /// <param name="stateinfo"></param>

        public void UploadFile( object stateinfo )

        {

            int nRealRead, nBufferSize;

            const int BUFFER_SIZE = 10240;

 

            using( FileStream fs = new FileStream( strFileName,

                       FileMode.Open, FileAccess.Read,

                       FileShare.Read ) )

            {

                string sName = strFileName.Substring( strFileName.LastIndexOf( "//" ) + 1 );

                byte[] bBuffer = new byte[BUFFER_SIZE];//Init 10k buffer

                fs.Position = nStartPos;

                nRealRead = 0;

                do

                {

                    nBufferSize = BUFFER_SIZE;

                    if( nRealRead + BUFFER_SIZE > nTotalBytes )

                        nBufferSize = nTotalBytes - nRealRead;

 

                    nBufferSize = fs.Read( bBuffer, 0, nBufferSize );

                    if( nBufferSize == BUFFER_SIZE )

                        UploadHandle( sName,

                            nRealRead + nStartPos,

                            bBuffer );

                    else if( nBufferSize > 0 )

                    {

                        //Copy data

                        byte[] bytData = new byte[nBufferSize];

                        Array.Copy( bBuffer,0, bytData, 0, nBufferSize );

 

                        UploadHandle( sName,

                            nRealRead + nStartPos,

                            bytData );

                    }

 

                    nRealRead += nBufferSize;

                }

                while( nRealRead < nTotalBytes );

            }

            //Release signal

            ManualResetEvent mr = stateinfo as ManualResetEvent;

            if( mr != null )

                mr.Set();

        }

    }

 

那么在执行的时候,要创建线程类对象,并为每一个每个线程设置一个信号量,从而能在所有线程都结束的时候得到通知,大致的代码如下。

    FileInfo fi = new FileInfo( txtFileName.Text );

    if( fi.Exists )

    {

        btnUpload.Enabled = false;//Avoid upload twice

 

        //Init signals

        ManualResetEvent[] events = new ManualResetEvent[5];

 

        //Devide blocks

        int nTotalBytes = (int)( fi.Length / 5 );

        for( int i = 0; i < 5; i++ )

        {

            events[i] = new ManualResetEvent( false );

            FileThread thdSub = new FileThread(

                i * nTotalBytes,

                ( fi.Length - i * nTotalBytes ) > nTotalBytes ? nTotalBytes:(int)( fi.Length - i * nTotalBytes ),

                fi.FullName );

            ThreadPool.QueueUserWorkItem( new WaitCallback( thdSub.UploadFile ), events[i] );

        }

 

        //Wait for threads finished

        WaitHandle.WaitAll( events );

 

        //Reset button status

        btnUpload.Enabled = true;

    }

 

总体来说,程序还是相对比较简单,而我也只是做了个简单例子而已,一些细节都没有进行处理。

 

本来想打包提供给大家下载,没想到优快云的Blog对于这点做的太差,老是异常。

如下是客户端的完整代码。

//--------------------------- Multi-thread Upload Demo ---------------------------------------

//--------------------------------------------------------------------------------------------

//---File:          frmUpload

//---Description:   The multi-thread upload form file to demenstrate howto use multi-thread to

//                  upload files

//---Author:        Knight

//---Date:          Oct.12, 2006

//--------------------------------------------------------------------------------------------

//---------------------------{Multi-thread Upload Demo}---------------------------------------

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

 

namespace CSUpload

{

    using System.IO;

    using System.Diagnostics;

    using System.Threading;

    using WSUploadFile;//Web-service reference namespace

 

    /// <summary>

    /// Summary description for Form1.

    /// </summary>

    public class frmUpload : System.Windows.Forms.Form

    {

        private System.Windows.Forms.TextBox txtFileName;

        private System.Windows.Forms.Button btnBrowse;

        private System.Windows.Forms.Button btnUpload;

        /// <summary>

        /// Required designer variable.

        /// </summary>

        private System.ComponentModel.Container components = null;

 

        public frmUpload()

        {

            //

            // Required for Windows Form Designer support

            //

            InitializeComponent();

 

            //

            // TODO: Add any constructor code after InitializeComponent call

            //

        }

 

        /// <summary>

        /// Clean up any resources being used.

        /// </summary>

        protected override void Dispose( bool disposing )

        {

            if( disposing )

            {

                if (components != null)

                {

                    components.Dispose();

                }

            }

            base.Dispose( disposing );

        }

 

        #region Windows Form Designer generated code

        /// <summary>

        /// Required method for Designer support - do not modify

        /// the contents of this method with the code editor.

        /// </summary>

        private void InitializeComponent()

        {

            this.txtFileName = new System.Windows.Forms.TextBox();

            this.btnBrowse = new System.Windows.Forms.Button();

            this.btnUpload = new System.Windows.Forms.Button();

            this.SuspendLayout();

            //

            // txtFileName

            //

            this.txtFileName.Location = new System.Drawing.Point(16, 24);

            this.txtFileName.Name = "txtFileName";

            this.txtFileName.Size = new System.Drawing.Size(248, 20);

            this.txtFileName.TabIndex = 0;

            this.txtFileName.Text = "";

            //

            // btnBrowse

            //

            this.btnBrowse.Location = new System.Drawing.Point(272, 24);

            this.btnBrowse.Name = "btnBrowse";

            this.btnBrowse.TabIndex = 1;

            this.btnBrowse.Text = "&Browse...";

            this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);

            //

            // btnUpload

            //

            this.btnUpload.Location = new System.Drawing.Point(272, 56);

            this.btnUpload.Name = "btnUpload";

            this.btnUpload.TabIndex = 2;

            this.btnUpload.Text = "&Upload";

            this.btnUpload.Click += new System.EventHandler(this.btnUpload_Click);

            //

            // frmUpload

            //

            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

            this.ClientSize = new System.Drawing.Size(370, 111);

            this.Controls.Add(this.btnUpload);

            this.Controls.Add(this.btnBrowse);

            this.Controls.Add(this.txtFileName);

            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;

            this.MaximizeBox = false;

            this.Name = "frmUpload";

            this.Text = "Upload";

            this.Load += new System.EventHandler(this.frmUpload_Load);

            this.ResumeLayout(false);

 

        }

        #endregion

 

        /// <summary>

        /// The main entry point for the application.

        /// </summary>

        static void Main()

        {

            Application.Run(new frmUpload());

        }

 

        private FileUpload myUpload = new FileUpload();

        private void UploadData( string FileName, int StartPos, byte[] bData )

        {

            //Call web service upload

            myUpload.UploadFileData( FileName, StartPos, bData );

        }

 

        private void btnUpload_Click(object sender, System.EventArgs e)

        {

            FileInfo fi = new FileInfo( txtFileName.Text );

            if( fi.Exists )

            {

                btnUpload.Enabled = false;//Avoid upload twice

 

                //Init signals

                ManualResetEvent[] events = new ManualResetEvent[5];

 

                //Devide blocks

                int nTotalBytes = (int)( fi.Length / 5 );

                for( int i = 0; i < 5; i++ )

                {

                    events[i] = new ManualResetEvent( false );

                    FileThread thdSub = new FileThread(

                        i * nTotalBytes,

                        ( fi.Length - i * nTotalBytes ) > nTotalBytes ? nTotalBytes:(int)( fi.Length - i * nTotalBytes ),

                        fi.FullName );

                    ThreadPool.QueueUserWorkItem( new WaitCallback( thdSub.UploadFile ), events[i] );

                }

 

                //Wait for threads finished

                WaitHandle.WaitAll( events );

 

                //Reset button status

                btnUpload.Enabled = true;

            }

       

        }

 

        private void frmUpload_Load(object sender, System.EventArgs e)

        {

            FileThread.UploadHandle = new UploadFileData( this.UploadData );

        }

 

        private void btnBrowse_Click(object sender, System.EventArgs e)

        {

            if( fileOpen.ShowDialog() == DialogResult.OK )

                txtFileName.Text = fileOpen.FileName;

        }

        private OpenFileDialog fileOpen = new OpenFileDialog();

       

 

    }

 

    public delegate void UploadFileData( string FileName, int StartPos, byte[] bData );

 

    /// <summary>

    /// FileThread: a class for sub-thread

    /// </summary>

    sealed class FileThread

    {

        private int nStartPos;

        private int nTotalBytes;

        private string strFileName;

        public static UploadFileData UploadHandle;

 

        /// <summary>

        /// Constructor

        /// </summary>

        /// <param name="StartPos"></param>

        /// <param name="TotalBytes"></param>

        /// <param name="FileName"></param>

        public FileThread( int StartPos, int TotalBytes, string FileName )

        {

            //Init thread variant

            nStartPos = StartPos;

            nTotalBytes = TotalBytes;

            strFileName = FileName;

 

            //Only for debug

            Debug.WriteLine( string.Format( "File name:{0} position: {1} total byte:{2}",

                strFileName, nStartPos, nTotalBytes ) );

        }

 

        /// <summary>

        /// Sub-thread entry function

        /// </summary>

        /// <param name="stateinfo"></param>

        public void UploadFile( object stateinfo )

        {

            int nRealRead, nBufferSize;

            const int BUFFER_SIZE = 10240;

 

            using( FileStream fs = new FileStream( strFileName,

                       FileMode.Open, FileAccess.Read,

                       FileShare.Read ) )

            {

                string sName = strFileName.Substring( strFileName.LastIndexOf( "//" ) + 1 );

                byte[] bBuffer = new byte[BUFFER_SIZE];//Init 10k buffer

                fs.Position = nStartPos;

                nRealRead = 0;

                do

                {

                    nBufferSize = BUFFER_SIZE;

                    if( nRealRead + BUFFER_SIZE > nTotalBytes )

                        nBufferSize = nTotalBytes - nRealRead;

 

                    nBufferSize = fs.Read( bBuffer, 0, nBufferSize );

                    if( nBufferSize == BUFFER_SIZE )

                        UploadHandle( sName,

                            nRealRead + nStartPos,

                            bBuffer );

                    else if( nBufferSize > 0 )

                    {

                        //Copy data

                        byte[] bytData = new byte[nBufferSize];

                        Array.Copy( bBuffer,0, bytData, 0, nBufferSize );

 

                        UploadHandle( sName,

                            nRealRead + nStartPos,

                            bytData );

                    }

 

                    nRealRead += nBufferSize;

                }

                while( nRealRead < nTotalBytes );

            }

            //Release signal

            ManualResetEvent mr = stateinfo as ManualResetEvent;

            if( mr != null )

                mr.Set();

        }

    }

 

}

 

从零搭建自动驾驶仿真环境:我的Nuplan-devkit实战笔记(含PyCharm配置技巧) 本文详细记录了从零搭建Nuplan-devkit自动驾驶仿真环境的完整流程,包括conda环境配置、pip版本控制、PyCharm专业版集成等关键步骤。特别针对Ubuntu系统下的依赖管理、数据目录优化和性能调优提供了实用技巧,帮助开发者高效构建稳定的自动驾驶仿真开发环境。 阅读详情

相关推荐

信息抽取实战:三元组抽取(限定领域 vs 开放领域)(附代码)

信息抽取实战:三元组抽取 目录信息抽取实战:三元组抽取一、限定领域的三元组抽取比赛介绍数据分析序列标注模型关系分类模型三元组提取总结开放领域的三元组抽取标注平台文本分类新数据进行三元组抽取总结参考文献 一、限定领域的三元组抽取   本项目将会介绍在2019语言与智能技术竞赛的三元组抽取比赛方面的一次尝试。由于该比赛早已结束,当时也没有参加这个比赛,因此没有测评成绩,我们也只能拿到训练集和验证集。但是,这并不耽误我们在这方面做实验。 比赛介绍   该比赛的网址为:http://lic2019.ccf.org.

南有芙蕖 2万+

三、【C++项目】WebServer-多线程开发-详细笔记

目录。

wjh19970930的博客 1859

变压器耦合放大器(低频应用+高频应用)

变压器耦合放大器(低频应用+高频应用)

m0_54943120的博客 2275

C#多线程调用webservice操作超时

正常情况下,调一个WebService是不成问题的,可是在多线程下,每个线程调一个WebService(都是不同URL的WebService),只有在编译后调第一遍是正常的,再调就报错啊,无法从命名空间“****”导入绑定“SyncToContractDataCenterSoap”,或者是调用目标异常,坑爹啊。在.net中,可以添加Web 引用来添加WebService,但是这种方法的缺陷是当WebService内的方法一变动,引用的系统这边就必须更新引用,重新编译,再发布,是不是很麻烦?

qq_39367709的博客 1283

在 STM32CubeIDE 中针对 STM32F407 移植 ThreadX

在 STM32CubeIDE 中针对 STM32F407 移植 ThreadX,不依赖盗版破解的Keil MDK、IAR等软件。

wangyuewu08的博客 3374

TCN实战:用Python手把手搭建时序预测模型(附完整代码)

本文详细介绍了如何使用Python搭建TCN(Temporal Convolutional Network)时序预测模型,包括数据预处理、模型架构实现、训练调优及预测评估。通过完整的代码示例和实用技巧,帮助开发者快速掌握TCN在时间序列预测中的应用,特别适合处理长期依赖问题。

weixin_29041195的博客 372

C#.NET大文件分片上传/多线程上传

50 --验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修改过--------------70 -------添加重要响应头、解析请求头、相关验证-------------------7 /// Range:续传的起始位置,即已经下载到客户端的字节数,值如:bytes=1474560-。98 -------向客户端发送数据块-------------------

Mr_Zang666的博客 510

AIGC内容溯源技术:如何追踪AI生成内容的原始来源

本文旨在系统性地介绍AIGC内容溯源的技术体系,帮助读者理解如何追踪AI生成内容的来源。我们将覆盖从基础概念到前沿技术的完整知识链,包括但不限于数字水印、区块链存证、内容指纹等技术方案。文章将从AIGC的基本概念出发,逐步深入探讨各种溯源技术,分析其原理和实现,最后讨论实际应用和未来趋势。AIGC:AI Generated Content,人工智能生成内容内容溯源:追踪数字内容的创作、修改和传播历史数字水印:嵌入在数字内容中的不可见识别信息数字水印:隐藏在内容中的识别信息,像隐形墨水内容指纹。

SuperAGI2025 2070

借助WebService C#实现多线程上传文件

<br />在WebService的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础上进行扩展。<br />首先说说服务器端,只需要提供一个能允许多线程写文件的函数即可,具体代码如下。<br />[WebMethod]<br />publicbool UploadFileData( string FileName, int StartPosition, byte[] bData )<br />{<br />    string strFullName

程序亦人生 4575

Linux服务器 离线安装oracle

Linux服务器 离线安装oracle

xie_bro的博客 4256

2025年09月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析

2025年09月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析

伶俐角少儿编程 639

[转载]借助WebService实现多线程上传文件

借助WebService实现多线程上传文件借助WebService实现多线程上传文件 在WebService的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础...

congji3817的博客 152

AIGC实战——变分自编码器(Variational Autoencoder, VAE)

变分自编码器通过在模型中引入随机性,并限制潜空间中的点的分布来解决自编码器存在的问题。只需进行一些微小的调整,就可以将自编码器转换为变分自编码器,从而使其成为真正的生成模型。在本节中,我们介绍了变分自编码器的基本原理,并使用 `Keras` 实现了一个变分自编码器用于生成 Fashion-MNIST 图像。

盼小辉丶的博客 1万+

大文件HTTP上传的几种实现思路

1、采用webservice和客户端应用程序的方法。     在客户端将文件转成数据流,然后将数据的每一部分发送给WebService,由WebService将数据保存到服务器上,这种方法可上传超过10G的文件到服务器(经过测试),但是这种方法在具体实现的时候,比较麻烦。必须同时完成WebService和客户端两部分代码。或者采用ActiveX在网页上实现。他的好处是能够监测全部的文件上传过程,并

夜雨悠扬 的专栏 1770

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C# WinForm开发系列 - File

介绍文件目录相关操作, 涉及配置文件使用, 编码转换, Web下载, 加密处理等. (文章及相关代码搜集自网络,仅供学习参考,版权属于原作者! )  01. 愚翁专栏 优快云第一期总结之四:Stream的问题 对于Stream相关的问题,大致分如下几类。问题一,基本操作的问题;问题二,编码的问题;问题三,尾部处理问题;问题四,Stream缓存问题;问题五,资源释放问题;最后一个问题,说...

weixin_33742618的博客 199

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

上一篇: 《Effective C#》Part II:第二部分总结
下一篇: 《Effective C#》Item 19:推荐在继承中使用接口
Knight94
博客等级 码龄25年 1013粉丝 87原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值