【发布时间】:2018-08-25 22:13:29
【问题描述】:
我在 .NET Core 2.0 上的 Microsoft.AzureStorage 9.1 Nuget 包中遇到了 DownloadRangeToByteArrayAsync 方法的问题。每当我以并行或异步方式执行 DownloadRangeToByteArrayAsync 时,都会导致任何后续耗时操作的性能问题。这是我使用的代码:
static void Main(string[] args)
{
var storageAccount = CloudStorageAccount.Parse("<access_string>");
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("<container_name>");
List<CloudBlockBlob> listBlobs = new List<CloudBlockBlob>();
for (int c = 0; c < 100; c++)
{
listBlobs.Add(container.GetBlockBlobReference("<file_name>"));
}
var tasks = listBlobs.Select(async bl =>
{
byte[] buffer = new byte[128];
await bl.DownloadRangeToByteArrayAsync(buffer, 0, 65536, 128);
return buffer;
});
Task.WaitAll(tasks.ToArray());
for (int c = 0; c < 100; c++)
{
Stopwatch sw = Stopwatch.StartNew();
byte[] buffer = new byte[1024];
listBlobs[0].DownloadRangeToByteArrayAsync(buffer, 0, 65536 * c, 1024).Wait();
Console.WriteLine(sw.ElapsedMilliseconds);
}
Console.Read();
}
}
当我执行上述代码时,在 Task.WaitAll() 之后,以下循环的每次迭代都需要很长时间。与我的代码中没有包含 Task.WaitAll 相比,每次迭代花费的时间是 4 倍以上。与在 .NET Framework 4.6.1(也使用 WindowsAzure.Storage 9.1.0)中执行完全相同的代码所花费的时间也增加了 4 倍。用 Parallel.ForEach 替换 Select 语句也会导致同样的问题,但如果我在 DownloadRangeToByteArrayAsync 上使用 .Wait() 而不是 await 就可以了。同样经过大约 2 分钟的 LINQ/Parallel 语句,所有后续操作的运行时间都恢复正常。此外,当我调试它时,它显示 LINQ 语句(或 Parallel.ForEach)在 .NET Core 上创建了 100 多个线程,而在 .NET Framework 上只创建了大约 10 个。此外,这 100 多个线程中的大多数都没有消失,即使在一个多小时后也是如此。
有谁知道导致问题的 DownloadRangeToByteArrayAsync 或线程从 .NET Framework 4.6.1 更改为 .NET Core 2.0 是怎么回事?
【问题讨论】:
标签: c# multithreading async-await .net-core azure-blob-storage