多线程-任务.当下载blob存储文件时



我有以下代码下载blob文件为字符串。它工作得很好,但性能很差。处理500个文件大约需要50秒。'

try
{
var sourceClient = new BlobServiceClient(storageConnectionString);
var foundItems = sourceClient.FindBlobsByTags("Client = 'TEST'").ToList();
foreach (var blob in foundItems)
{
var blobClient = blobContainer.GetBlockBlobClient(blob.BlobName);
BlobDownloadResult download = await blobClient.DownloadContentAsync();
string downloadedData = download.Content.ToString();
myList.Add(downloadedData);
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");`
}
`   

我尝试了多线程的代码,但仍然需要大约25秒来处理500个文件。

var semaphore = new SemaphoreSlim(50);
var tasks = new List<Task>();
try
{
var sourceClient = new BlobServiceClient(storageConnectionString);
var foundItems = sourceClient.FindBlobsByTags("Client = 'TEST'").ToList();
foreach (var blob in foundItems)
{
tasks.Add(Task.Run(async () =>
{
try
{
await semaphore.WaitAsync();
var blobClient = blobContainer.GetBlockBlobClient(blob.BlobName);
BlobDownloadResult download = await blobClient.DownloadContentAsync();
string downloadedData = download.Content.ToString();
myList.Add(downloadedData);
;
}
finally
{
semaphore.Release();
}
}));
}
await Task.WhenAll(tasks);
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}

我对c#很陌生,我在多线程方面有什么问题吗?从blob存储中读取文件的最快方法是什么?

注意:下面这行代码会导致最大的延迟。

BlobDownloadResult download = await blobClient.DownloadContentAsync();

你的代码有两个最大的性能问题:

  • 不要在Task.Run中包装下载任务,你只是无缘无故地使用线程池线程。
  • 停止无理由切换上下文,在await呼叫中使用.ConfigureAwait(false)

第三个问题,比较起来比较小:

  • 您正在通过从多个线程推送到List<>来破坏内存。使用合适的并发容器,如ConcurrentBag<>。编辑:事实上,我甚至不相信你需要列表,使用Task.WhenAll的返回值来收集结果,而不是手工收集结果。

最新更新