打算用FtpWebRequest,
如何同时upload多个文件呢,threadpool? 求code。想做一个和skydrive upload类似的dll。

解决方案 »

  1.   

    下面的内容有谁实践过?
    http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx 
      

  2.   

    我自己琢磨了一个,windform application, code如下,可是在运行时,这段代码exception,
    一下这段代码在 Upload()method中
    // The operations either completed or threw an exception.
                if (state.OperationException != null)
                {
                    throw state.OperationException;“这里报错”
                }
                else
                {
                    uploadStatus = string.Format("The operation completed - {0}", state.StatusDescription);
                }
     
    WebException 内容如下:
    The remote server returned an error: (550) File unavailable (e.g., file not found, no access).完整代码如下:using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    using System.Net;
    using System.IO;namespace AsynchronousUpload
    {
        public partial class Form1 : Form
        {
           
            private string host = "ftp://ftp.abc.com/Test/";
            private string user = "abc";
            private string password = "abc";
            private string uploadStatus;
            private string localFile;
            private string remoteFile;
            private string[] localFiles;
            private string[] remotelFiles;
            
            
            public Form1()
            {
                InitializeComponent();
            }        private void btnUpload_Click(object sender, EventArgs e)
            {
                localFiles = new string[] { txtLocalFile.Text, txtLocalFile2.Text };
                remotelFiles = new string[] { txtRemoteFile.Text, txtRemoteFile2.Text };
                for (int i = 0; i <= 1; i++)
                {
                    localFile = localFiles[i];
                    remoteFile = remotelFiles[i];
                    Thread t = new Thread(Upload);
                    t.Name = "Thread_" + i;
                    t.Start();
                }
            }
            private void Upload()
            {
                
                // Create a Uri instance with the specified URI string.
                // If the URI is not correctly formed, the Uri constructor
                // will throw an exception.
                ManualResetEvent waitObject;            Uri target = new Uri(host + remoteFile);
                string fileName = localFile;
                FtpState state = new FtpState();
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
                request.Method = WebRequestMethods.Ftp.UploadFile;
                //request.Timeout = 600000; //Set a time limit for the operation to complete.
                //request.ReadWriteTimeout = 10000; //when reading or writing to a stream.
                request.KeepAlive = false;
                request.UseBinary = true;            // control how actions are logged on the server.            request.Credentials = new NetworkCredential(user, password);            // Store the request in the object that we pass into the
                // asynchronous operations.
                state.Request = request;
                state.FileName = fileName;            // Get the event to wait on.
                waitObject = state.OperationComplete;            // Asynchronously get the stream for the file contents.
                request.BeginGetRequestStream(
                    new AsyncCallback(EndGetStreamCallback),
                    state
                );            // Block the current thread until all operations are complete.
                waitObject.WaitOne();            // The operations either completed or threw an exception.
                if (state.OperationException != null)
                {
                    throw state.OperationException;
                }
                else
                {
                    uploadStatus = string.Format("The operation completed - {0}", state.StatusDescription);
                }
     
            }        private static void EndGetStreamCallback(IAsyncResult ar)
            {
                FtpState state = (FtpState)ar.AsyncState;            Stream requestStream = null;
                // End the asynchronous call to get the request stream.
                try
                {
                    requestStream = state.Request.EndGetRequestStream(ar);
                    // Copy the file contents to the request stream.
                    const int bufferLength = 2048;
                    byte[] buffer = new byte[bufferLength];
                    int count = 0;
                    int readBytes = 0;
                    FileStream stream = File.OpenRead(state.FileName);
                    do
                    {
                        readBytes = stream.Read(buffer, 0, bufferLength);
                        requestStream.Write(buffer, 0, readBytes);
                        count += readBytes;
                    }
                    while (readBytes != 0);
                    //Console.WriteLine("Writing {0} bytes to the stream.", count);
                    // IMPORTANT: Close the request stream before sending the request.
                    requestStream.Close();
                    stream.Close();
                    // Asynchronously get the response to the upload request.
                    state.Request.BeginGetResponse(
                        new AsyncCallback(EndGetResponseCallback),
                        state
                    );
                }
                // Return exceptions to the main application thread.
                catch (Exception e)
                {
                    //Console.WriteLine("Could not get the request stream.");
                    state.OperationException = e;
                    state.OperationComplete.Set();
                    return;
                }        }        // The EndGetResponseCallback method  
            // completes a call to BeginGetResponse.
            private static void EndGetResponseCallback(IAsyncResult ar)
            {
                FtpState state = (FtpState)ar.AsyncState;
                FtpWebResponse response = null;
                try
                {
                    response = (FtpWebResponse)state.Request.EndGetResponse(ar);
                    response.Close();
                    state.StatusDescription = response.StatusDescription;
                    // Signal the main application thread that 
                    // the operation is complete.
                    state.OperationComplete.Set();
                }
                // Return exceptions to the main application thread.
                catch (Exception e)
                {
                    //Console.WriteLine("Error getting response.");
                    state.OperationException = e;
                    state.OperationComplete.Set();
                }
            }        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                for (int i = 0; i<=1; i++)
                {
                    localFile = localFiles[i];
                    remoteFile = remotelFiles[i];
                    Upload();
                }
                
            }    }
    }FtpState class 如下:using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Net;namespace AsynchronousUpload
    {
        class FtpState
        {
            private ManualResetEvent wait;
            private FtpWebRequest request;
            private string fileName;
            private Exception operationException = null;
            string status;        public FtpState()
            {
                wait = new ManualResetEvent(false);
            }        public ManualResetEvent OperationComplete
            {
                get {return wait;}
            }        public FtpWebRequest Request
            {
                get {return request;}
                set {request = value;}
            }        public string FileName
            {
                get {return fileName;}
                set {fileName = value;}
            }
            public Exception OperationException
            {
                get {return operationException;}
                set {operationException = value;}
            }
            public string StatusDescription
            {
                get {return status;}
                set {status = value;}
            }
        }
    }
      

  3.   

    只是简单调用Upload() 没有问题。好像用Thread不当。private void btnUpload_Click(object sender, EventArgs e)
    {
        localFiles = new string[] { txtLocalFile.Text, txtLocalFile2.Text };
        remotelFiles = new string[] { txtRemoteFile.Text, txtRemoteFile2.Text };
        localFile = localFiles[0];
        remoteFile = remotelFiles[0];
        Upload();
         localFile = localFiles[1];
        remoteFile = remotelFiles[1];
        Upload();}这样用没有问题,可是这样不就变成一次upload一个文件,一次只upload一个文件,那很简单。我是想同时upload多个文件。
    MSDN 上的AsynchronousUpload
    http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx  
    好像也没有什么用啊?要不就是我还不理解。
      

  4.   

    如果我在一下每个循环中间设个断点,等待一会,整个程序就可以运行了,可以在ftp server上看到有2个文件在上传。
    for (int i = 0; i <= 1; i++)
    {
       localFile = localFiles[i];
       remoteFile = remotelFiles[i];
       Thread t = new Thread(Upload);
       t.Name = "Thread_" + i;
       t.Start();
    }
     
      

  5.   

    加上Thread.Sleep(100);整个application就行了
    for (int i = 0; i <= 1; i++)
    {
      localFile = localFiles[i];
      remoteFile = remotelFiles[i];
      Thread t = new Thread(Upload);
      t.Name = "Thread_" + i;
      t.Start();
      Thread.Sleep(100)//10 也行,是个数就行,虽然还是不跟理解,可是程序工作了。
    }