C# 限制并发异步任务
我想使用C# 限制并发异步任务,c#,async-await,semaphore,C#,Async Await,Semaphore,我想使用SSH.NET库和扩展名将可能大批量(可能是100个)的文件上传到FTP。我需要将并发上传的数量限制在5个,或者我发现FTP可以处理的任何数量 这是我在任何限制之前的代码: using (var sftp = new SftpClient(sftpHost, 22, sftpUser, sftpPass)) { var tasks = new List<Task>(); try { sftp.Connect(); fo
SSH.NET
库和扩展名将可能大批量(可能是100个)的文件上传到FTP。我需要将并发上传的数量限制在5个,或者我发现FTP可以处理的任何数量
这是我在任何限制之前的代码:
using (var sftp = new SftpClient(sftpHost, 22, sftpUser, sftpPass))
{
var tasks = new List<Task>();
try
{
sftp.Connect();
foreach (var file in Directory.EnumerateFiles(localPath, "*.xml"))
{
tasks.Add(
sftp.UploadAsync(
File.OpenRead(file), // Stream input
Path.GetFileName(file), // string path
true)); // bool canOverride
}
await Task.WhenAll(tasks);
sftp.Disconnect();
}
// trimmed catch
}
据我所知,Task.Run用于CPU限制的工作
对
异步/等待I/O绑定工作
否。await
是一种用于向异步操作添加连续性的工具。它不关心异步操作的性质。它只是使将任何类型的异步操作组合在一起变得更容易
如果要将多个异步操作组合在一起,可以使用各种异步操作创建一个async
方法,在需要它们的结果时等待它们(或等待它们完成),然后使用任务将该方法作为其自己的新异步操作
在您的情况下,新的异步操作只需要等待信号量,上载文件,然后释放信号量
async Task UploadFile()
{
await semaphore.WaitAsync();
try
{
await sftp.UploadAsync(
File.OpenRead(file),
Path.GetFileName(file),
true));
}
finally
{
semaphore.Release();
}
}
现在,您可以简单地为每个文件调用该方法
此外,由于这是一个非常常见的操作,您可能会发现它是值得的,因此您可以简单地创建一个队列,并向队列中添加项目,让它在内部处理节流,而不是在您使用它的任何地方复制该机制。您查看过线程池吗?特别是问题中提到的@DotNetPadawan,这不是CPU限制的工作。它不会将线程池用于实际的长时间运行操作。可能重复
async Task UploadFile()
{
await semaphore.WaitAsync();
try
{
await sftp.UploadAsync(
File.OpenRead(file),
Path.GetFileName(file),
true));
}
finally
{
semaphore.Release();
}
}