| 導購 | 订阅 | 在线投稿
分享
 
 
 

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

2008-12-13 08:23:55  編輯來源:互聯網  简体版  手機版  評論  字體: ||
 
  在WebService的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础上进行扩展。

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

  [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;

  

  }

  [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用户对此目录具有可写权限。

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

  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();

  

  }

  

  }

  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();

  }

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

  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;

  

  }

  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;

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

  如下是客户端的完整代码。view plaincopy to clipboardprint?

  //--------------------------- 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();

  

  }

  

  }

  

  

  

  }
 
 
 
  在WebService的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础上进行扩展。   首先说说服务器端,只需要提供一个能允许多线程写文件的函数即可,具体代码如下。view plaincopy to clipboardprint? [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; } [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用户对此目录具有可写权限。   相对于服务器端来说,客户端要稍微复杂一些,因为要牵扯到多线程的问题。为了更好的传递参数,我用一个线程类来完成。具体如下。view plaincopy to clipboardprint? 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(); } } 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(); } }  那么在执行的时候,要创建线程类对象,并为每一个每个线程设置一个信号量,从而能在所有线程都结束的时候得到通知,大致的代码如下。view plaincopy to clipboardprint? 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; } 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; }  总体来说,程序还是相对比较简单,而我也只是做了个简单例子而已,一些细节都没有进行处理。   如下是客户端的完整代码。view plaincopy to clipboardprint? //--------------------------- 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(); } } }
󰈣󰈤
 
 
 
>>返回首頁<<
 
 
 
 
 
 熱帖排行
 
 
王朝网络微信公众号
微信扫码关注本站公众号 wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味著赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有