Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何提高通过流下载大型azure blob文件的性能?_C#_.net_Azure_.net Core_Azure Storage Blobs - Fatal编程技术网

C# 如何提高通过流下载大型azure blob文件的性能?

C# 如何提高通过流下载大型azure blob文件的性能?,c#,.net,azure,.net-core,azure-storage-blobs,C#,.net,Azure,.net Core,Azure Storage Blobs,我有大小约为212MB的JSON blob文件 在本地进行调试时,下载大约需要15分钟。 当我将代码部署到Azure应用程序服务时,它会运行10分钟,并出现错误:(在本地,它会间歇性地出现相同的错误) 服务器无法对请求进行身份验证。确保 授权标头的格式正确,包括签名 代码尝试1: // Create SAS Token for referencing a file for a duration of 5 min SharedAccessBlobPolicy sasConstraints = ne

我有大小约为212MB的JSON blob文件
在本地进行调试时,下载大约需要15分钟。
当我将代码部署到Azure应用程序服务时,它会运行10分钟,并出现错误:(在本地,它会间歇性地出现相同的错误)

服务器无法对请求进行身份验证。确保 授权标头的格式正确,包括签名

代码尝试1:

// Create SAS Token for referencing a file for a duration of 5 min
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy
{
    SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
    Permissions = SharedAccessBlobPermissions.Read
};

var blob = cloudBlobContainer.GetBlockBlobReference(blobFilePath);
string sasContainerToken = blob.GetSharedAccessSignature(sasConstraints);

var cloudBlockBlob = new CloudBlockBlob(new Uri(blob.Uri + sasContainerToken));

using (var stream = new MemoryStream())
{
     await cloudBlockBlob.DownloadToStreamAsync(stream);
    //resetting stream's position to 0

    stream.Position = 0;
    var serializer = new JsonSerializer();

    using (var sr = new StreamReader(stream))
    {
        using (var jsonTextReader = new JsonTextReader(sr))
        {
            jsonTextReader.SupportMultipleContent = true;
            result = new List<T>();
            while (jsonTextReader.Read())
            {
                result.Add(serializer.Deserialize<T>(jsonTextReader));
            }
        }
    }
}
//创建SAS令牌以引用文件,持续时间为5分钟
SharedAccessBlobPolicy sasConstraints=新的SharedAccessBlobPolicy
{
SharedAccessExpiryTime=DateTime.UtcNow.AddMinutes(15),
权限=SharedAccessBlobPermissions.Read
};
var blob=cloudBlobContainer.GetBlockBlobReference(blobFilePath);
字符串sasContainerToken=blob.GetSharedAccessSignature(sasConstraints);
var cloudBlockBlob=newcloudblockblob(新Uri(blob.Uri+sascannertoken));
使用(var stream=new MemoryStream())
{
等待cloudBlockBlob.DownloadToStreamAsync(流);
//正在将流的位置重置为0
流位置=0;
var serializer=new JsonSerializer();
使用(var sr=新的StreamReader(stream))
{
使用(var jsonTextReader=new jsonTextReader(sr))
{
jsonTextReader.SupportMultipleContent=true;
结果=新列表();
while(jsonTextReader.Read())
{
Add(serializer.Deserialize(jsonTextReader));
}
}
}
}
代码尝试2:我尝试使用DownloadRangeToStreamAsync下载区块中的blob,但没有任何更改:

int bufferLength = 1 * 1024 * 1024;//1 MB chunk
long blobRemainingLength = blob.Properties.Length;
Queue<KeyValuePair<long, long>> queues = new Queue<KeyValuePair<long, long>>();
long offset = 0;
do
{
    long chunkLength = (long)Math.Min(bufferLength, blobRemainingLength);

    offset += chunkLength;
    blobRemainingLength -= chunkLength;
    using (var ms = new MemoryStream())
    {
        await blob.DownloadRangeToStreamAsync(ms, offset, chunkLength);
        ms.Position = 0;
        lock (outPutStream)
        {
            outPutStream.Position = offset;
            var bytes = ms.ToArray();
            outPutStream.Write(bytes, 0, bytes.Length);
        }
    }
}
while (blobRemainingLength > 0);
int bufferLength=1*1024*1024//1 MB块
long blobRemainingLength=blob.Properties.Length;
队列=新队列();
长偏移=0;
做
{
long chunkLength=(long)Math.Min(bufferLength,blobRemainingLength);
偏移量+=长度;
blobRemainingLength-=块长度;
使用(var ms=new MemoryStream())
{
wait blob.DownloadRangeToStreamAsync(毫秒、偏移量、chunkLength);
ms.Position=0;
锁(输出流)
{
outPutStream.Position=偏移量;
var bytes=ms.ToArray();
outPutStream.Write(字节,0,字节.长度);
}
}
}
而(blobRemainingLength>0);
我认为212MB的数据不是一个大的JSON文件。你能推荐一个新的吗
解决方案?

我建议您可以使用试试

我测试了一个220MB的大文件,下载到内存大约需要5分钟

示例代码:

        SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
            Permissions = SharedAccessBlobPermissions.Read
        };

        CloudBlockBlob blob = blobContainer.GetBlockBlobReference("t100.txt");
        string sasContainerToken = blob.GetSharedAccessSignature(sasConstraints);
        var cloudBlockBlob = new CloudBlockBlob(new Uri(blob.Uri + sasContainerToken));

        var stream = new MemoryStream();

        //set this value as per your need
        TransferManager.Configurations.ParallelOperations = 5;

        Console.WriteLine("begin to download...");

        //use Stopwatch to calculate the time
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        DownloadOptions options = new DownloadOptions();
        options.DisableContentMD5Validation = true;

        //use these lines of code just for checking the downloading progress, you can remove it in your code.
        SingleTransferContext context = new SingleTransferContext();
        context.ProgressHandler = new Progress<TransferStatus>((progress) =>
        {
            Console.WriteLine("Bytes downloaded: {0}", progress.BytesTransferred);
        });

        var task = TransferManager.DownloadAsync(cloudBlockBlob, stream,options,context);
        task.Wait();

        stopwatch.Stop();
        Console.WriteLine("the length of the stream is: "+stream.Length);
        Console.WriteLine("the time is taken: "+stopwatch.ElapsedMilliseconds);
SharedAccessBlobPolicy sasConstraints=新的SharedAccessBlobPolicy
{
SharedAccessExpiryTime=DateTime.UtcNow.AddMinutes(15),
权限=SharedAccessBlobPermissions.Read
};
CloudBlockBlob blob=blobContainer.GetBlockBlobReference(“t100.txt”);
字符串sasContainerToken=blob.GetSharedAccessSignature(sasConstraints);
var cloudBlockBlob=newcloudblockblob(新Uri(blob.Uri+sascannertoken));
var stream=newmemoryStream();
//根据需要设置此值
TransferManager.Configurations.ParallelOperations=5;
Console.WriteLine(“开始下载…”);
//用秒表计算时间
秒表秒表=新秒表();
秒表。开始();
DownloadOptions=新的DownloadOptions();
options.DisableContentMD5Validation=true;
//使用这些代码行只是为了检查下载进度,您可以在代码中删除它。
SingleTransferContext=新的SingleTransferContext();
context.ProgressHandler=新进度((进度)=>
{
WriteLine(“下载的字节:{0}”,progress.ByTestTransfered);
});
var task=TransferManager.DownloadAsync(cloudBlockBlob、流、选项、上下文);
task.Wait();
秒表;
Console.WriteLine(“流的长度为:“+stream.length”);
Console.WriteLine(“所用时间:+stopwatch.ElapsedMilliseconds”);
测试结果:


您能否尝试将SAS的过期时间从15分钟增加到一小时?最有可能你的SAS在下载过程中过期。@ GuravaMtri增加SAS过期时间在本地工作,但部署后失败。存储帐户和应用程序服务位于同一资源组中是否仍会因相同的错误而失败?关于该错误还有更多详细信息吗?@GauravMantri我检查了网络,得到的post方法响应是:Web服务器在充当网关或代理服务器时收到无效响应。您正在查找的页面有问题,无法显示。当Web服务器(作为网关或代理)联系上游内容服务器时,它确实起作用了,就像您提到的,这需要5分钟。我欠你一个聚会。谢谢但有一个问题是,是否可以使用C#运行azure power shell脚本来提高流上的下载性能。@SagarK,为什么您认为在C#中运行powershell可以提高性能?我没有使用在c#中运行的powershell对其进行测试,但是
azure数据移动库
经过优化以获得更好的性能,MS建议将其用于更大的文件下载/上载。因为cmdlet已经编译了代码,这可能会提高性能。我也没有试过。是的,但您提供的使用azure数据移动库的解决方案工作正常。代码开始失败,出现outof Memory异常。补充问题: