繁体   English   中英

C#多线程-上传到FTP服务器

[英]C# Multi-threading - Upload to FTP Server

我想在您的C#程序中实现多线程方面寻求您的帮助。

该程序旨在将10,000 ++文件上传到ftp服务器。 我计划至少实现10个线程,以提高处理速度。

这样,这就是我拥有的代码行:

我已经初始化了10个线程:

public ThreadStart[] threadstart = new ThreadStart[10];
public Thread[] thread = new Thread[10];

我的计划是将一个文件分配给一个线程,如下所示:

file 1 > thread 1
file 2 > thread 2
file 3 > thread 3
.
.
.
file 10 > thread 10
file 11 > thread 1
.
.
.

因此,我有以下内容:

foreach (string file in files)
{
     loop++;

     threadstart[loop] = new ThreadStart(() => ftp.uploadToFTP(uploadPath + @"/" + Path.GetFileName(file), file));
     thread[loop] = new Thread(threadstart[loop]);
     thread[loop].Start();

     if (loop == 9)
     {
         loop = 0;
     }                          
}

正在将文件传递到其各自的线程。 我的问题是线程的启动是重叠的。

一个例外的示例是,当线程1运行时,会将文件传递给它。 由于线程1尚未成功完成,因此返回错误,然后将新参数传递给它。 其他线程也是如此。

实现此目的的最佳方法是什么?

任何反馈将不胜感激。 谢谢! :)

使用async-await并只向其中传递文件数组:

private static async void TestFtpAsync(string userName, string password, string ftpBaseUri,
      IEnumerable<string> fileNames)
    {
      var tasks = new List<Task<byte[]>>();
      foreach (var fileInfo in fileNames.Select(fileName => new FileInfo(fileName)))
      {
        using (var webClient = new WebClient())
        {
          webClient.Credentials = new NetworkCredential(userName, password);
          tasks.Add(webClient.UploadFileTaskAsync(ftpBaseUri + fileInfo.Name, fileInfo.FullName));
        }
      }
      Console.WriteLine("Uploading...");
      foreach (var task in tasks)
      {
        try
        {
          await task;
          Console.WriteLine("Success");
        }
        catch (Exception ex)
        {
          Console.WriteLine(ex.ToString());
        }
      }
    }

然后这样称呼它:

  const string userName = "username";
  const string password = "password";
  const string ftpBaseUri = "ftp://192.168.1.1/";
  var fileNames = new[] { @"d:\file0.txt", @"d:\file1.txt", @"d:\file2.txt" };
  TestFtpAsync(userName, password, ftpBaseUri, fileNames);

为什么要用困难的方式呢? .net已经有一个名为ThreadPool的类。 您可以使用它,它可以管理线程本身。 您的代码将如下所示:

 static void DoSomething(object n)
    {
        Console.WriteLine(n);
        Thread.Sleep(10);
    }

    static void Main(string[] args)
    {
        ThreadPool.SetMaxThreads(20, 10);
        for (int x = 0; x < 30; x++)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x);
        }
        Console.Read();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM