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 是 运行 时,一个文件被传递给它。它 returns 一个错误,因为线程 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 的 class。
你可以只使用它,它自己管理线程。
您的代码将是这样的:
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();
}
我想寻求您的帮助以在我的 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 是 运行 时,一个文件被传递给它。它 returns 一个错误,因为线程 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 的 class。 你可以只使用它,它自己管理线程。 您的代码将是这样的:
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();
}