【问题标题】:Upload multiple files efficiently asynchronously using ftp c#使用ftp c#高效地异步上传多个文件
【发布时间】:2013-02-14 06:11:57
【问题描述】:

我有这样的场景

while ( until toUpload list empty)
{
   create ftp folder (list.item);

   if (upload using ftp (list.item.fileName))
   {
     update Uploaded list that successfully updated;
   }
}

update database using Uploaded list;

这里我使用同步方法在这个循环中上传文件。我有一个要求优化这个上传。我找到了这篇文章How to improve the Performance of FtpWebRequest? 并按照他们提供的说明进行操作。因此我达到了 2000 秒到 1000 秒的时间。然后我开始使用异步上传,如 msdn 中的此示例所示。 http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest(v=vs.90).aspx。我改变了方法

if (upload using ftp (list.item.fileName)) 

if (aync upload using ftp (list.item.fileName))

但事情变得更糟了。时间变成 1000s 到 4000s。

我必须上传很多文件到我的 ftp 服务器。因此最好的方法应该是(猜测)异步的。有人帮助我如何以正确的方式做到这一点。我无法找到如何正确使用上面的 msdn 示例代码。

我的代码 - 同步(删除异常处理以节省空间):

public bool UploadFtpFile(string folderName, string fileName)
{     
  try
  {
    string absoluteFileName = Path.GetFileName(fileName);           

    var request = WebRequest.Create(new Uri(
      String.Format(@"ftp://{0}/{1}/{2}",
         this.FtpServer, folderName, absoluteFileName))) as FtpWebRequest;
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.UseBinary = true;
    request.UsePassive = true;
    request.KeepAlive = true;
    request.Credentials = this.GetCredentials();
    request.ConnectionGroupName = this.ConnectionGroupName; 
    request.ServicePoint.ConnectionLimit = 8; 

    using (FileStream fs = File.OpenRead(fileName))
    {
      byte[] buffer = new byte[fs.Length];
      fs.Read(buffer, 0, buffer.Length);
      fs.Close();
      using(var requestStream = request.GetRequestStream())
      {
        requestStream.Write(buffer, 0, buffer.Length);
      }
    }

    using (var response = (FtpWebResponse)request.GetResponse())
    {
        return true;
    }
  }
  catch // real code catches correct exceptions
  {
     return false;  
  }
}

异步方法

public bool UploadFtpFile(string folderName, string fileName)
{     
  try 
  {
    //this methods is exact method provide in msdn example mail method
    AsyncUploadFtp(String.Format(@"ftp://{0}/{1}/{2}", 
      this.FtpServer, folderName, Path.GetFileName(fileName)), fileName);

    return true;
  }
  catch // real code catches correct exceptions
  {
     return false;  
  }
}

【问题讨论】:

  • 不幸的是,10s 没有任何意义......您期望的速度是多少(即文件大小/最大上传速度)?你知道你是否真的可以发送比现在更多的数据吗? (也为了获得关于您的代码的一些合理建议,您需要展示至少看起来像 C# 代码的示例)。
  • 我添加了我的代码来提问,你知道你是否真的可以发送比现在更多的数据吗?我将 20 秒减少到 10 秒,上面的例子说他使用异步方法减少了 5 秒。在一般环境中,我将能够做同样的事情,因为我获得了第一个成就。请给我一些建议。
  • 建议 1:发布代码时,使其尽可能小且尽可能有用 - 即您已发布单个文件的同步上传代码,没有迭代代码或异步版本(最有可能与异步速度较慢是)。建议 2:独立于您的代码测量您的最大上传速度。建议 3:设定你的目标 - “10 秒很慢”不是一个,可能是“最多 1000 个文件,最大组合大小为 1TB 应在 3 秒内上传”。建议 4:分析您的代码。
  • 你在这里说多少个文件?如果您有很多文件,服务器可能无法一次处理所有文件,您可能会遇到超时/重试或上下文切换...
  • 我正在循环调用 UploadFtpFile 方法。当异步情绪时,我调用异步方法。所以它也在一个循环中。 10s是测试时间。实际时间几乎需要3个多小时。我使用的链接给我一个文件的上传速度 30kBps(链接是 128kBps)。在异步方法中,这变为 15 kBps。忘记10s的事情,这真的没用。

标签: c# optimization asynchronous ftp


【解决方案1】:

您是否尝试在 foreach 循环中使用它?

Task.Factory.StartNew(() => UploadFtpFile(folderName, filename));

【讨论】:

  • 我尝试了一些非常相似的方法,但我得到了一个 InnerException 说不支持多个并发连接。我不认为这是解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 2013-02-22
相关资源
最近更新 更多