如何解决Azure 存储:BlobClient 在上传大文件时不断重置自身
我正在尝试从连接到快速 Wifi 连接的手机上传 200 MB 的视频文件。我正在使用适用于 .NET 的 Azure 存储 SDK v12,但以下代码在大约 30% 的上传进度后不断自我重置。发生重置时,进度从0开始,不会抛出异常。
await blobClient.UploadAsync(stream,progressHandler: new Progress<long>(progress =>
{
// show progress bar
}),cancellationToken: cancellationToken);
v12 支持上传大文件吗?如果我没记错的话,旧的 API 能够上传单个块。我的印象是上述上传方法会隐式处理分块。
如何使用最新的 sdk 上传大文件?
附言我尝试以非常高的并发性和 1 MB 的传输大小传递 StorageTransferOptions
,但没有任何区别。
编辑:等了很长时间后,我能够抛出异常。我看到多个任务被取消,因为
Cannot access a disposed object.
Object name: 'MobileAuthenticatedStream'.
at Mono.Net.Security.MobileAuthenticatedStream.StartOperation (Mono.Net.Security.MobileAuthenticatedStream+OperationType type,Mono.Net.Security.AsyncProtocolRequest asyncRequest,System.Threading.CancellationToken cancellationToken) [0x00245] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:410
at System.Net.Http.HttpConnection.WriteAsync (System.ReadOnlyMemory`1[T] source) [0x00118] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs:1008
at System.IO.Stream.CopyToAsyncInternal (System.IO.Stream destination,System.Int32 bufferSize,System.Threading.CancellationToken cancellationToken) [0x000e7] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corert/src/System.Private.CoreLib/shared/System/IO/Stream.cs:152
at Azure.Core.RequestContent+StreamContent.WriteToAsync (System.IO.Stream stream,System.Threading.CancellationToken cancellation) [0x00094] in <7b1dc95b0b4841539beb48023c1128d3>:0
at Azure.Core.Pipeline.HttpClientTransport+PipelineRequest+PipelineContentAdapter.SerializeToStreamAsync (System.IO.Stream stream,System.Net.TransportContext context) [0x0007c] in <7b1dc95b0b4841539beb48023c1128d3>:0
at System.Net.Http.HttpContent.CopyToAsyncCore (System.Threading.Tasks.ValueTask copyTask) [0x00022] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpContent.cs:361
所以 blobClient
中似乎内置了并行化,但它仍然失败。此外,我无法使用 https://www.nuget.org/packages/Microsoft.Azure.Storage.DataMovement,因为它不适用于 Xamarin Forms
。
解决方法
如果要分块上传文件到Azure blob存储,请参考以下代码
public async Task upload(Stream stream){
string connectionString = "";
string containerName = "upload";
string blobName = "";
BlockBlobClient blobClient = new BlockBlobClient(connectionString,containerName,blobName);
List<string> blockList = new List<string>();
while (true) {
byte[] b = new byte[1024 * 1024];
var n = await stream.ReadAsync(b,1024 * 1024);
if (n == 0) break;
string blockId = Guid.NewGuid().ToString();
string base64BlockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId));
await blobClient.StageBlockAsync(base64BlockId,new MemoryStream(b,true));
blockList.Add(base64BlockId);
}
await blobClient.CommitBlockListAsync(blockList);
}
更新
如果要使用sas token,请参考以下代码
var uri = new Uri($"https://{storageAccountName}.blob.core.windows.net/{containerName}/{blobName}?{sasToken}");
BlockBlobClient blobClient = new BlockBlobClient(uri);
,
v12 同时具有 BlobClient 和 BlockBlobClient。就是BlockBlobClient,具有分块和上传块的功能。
你可以试试 Microsoft.Azure.Storage.DataMovement https://www.nuget.org/packages/Microsoft.Azure.Storage.DataMovement
"Microsoft Azure Storage DataMovement Library 提供了一组 API 扩展现有的 Azure Storage .Net 客户端库以帮助 客户传输具有高性能的 Azure Blob 和文件存储, 可扩展性和可靠性。”
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。