问题描述
我正在尝试从连接到快速Wifi连接的手机上载200 MB的视频文件.我使用的是适用于.NET的Azure存储SDK的v12,但以下代码会在上载进度达到30%左右后自行重置.发生重置时,进度从0开始,并且不会引发异常.
I'm trying to upload a 200 MB video file from a mobile phone that's connected to a fast Wifi connection. I'm using v12 of Azure Storage SDK for .NET, but the below code keeps resetting itself after about 30% upload progress. When the reset occurs, progress begins from 0 and there is no exception thrown.
await blobClient.UploadAsync(stream, progressHandler: new Progress<long>(progress =>
{
// show progress bar
}), cancellationToken: cancellationToken);
v12是否支持上传大文件?如果我没记错的话,旧的API可以上传单个块.我的印象是上述上传方法将隐式处理分块.
Does v12 support uploading large files? If I remember correctly, the old APIs had the ability to upload individual blocks. I was under the impression that the above upload method would handle chunking implicitly.
如何使用最新的sdk上传大文件?
How can I upload large files using the latest sdk?
P.S.我尝试传递具有很高的并发性和1 MB传输大小的 StorageTransferOptions
,但这没什么区别.
P.S. I tried passing a StorageTransferOptions
with very high concurrency and 1 MB transfer size, but it made no difference.
编辑:等待了很长一段时间后,我才能引发异常.我看到由于以下原因,多个任务被取消了:
After waiting for a long time, I was able to get an exception thrown. I see that multiple tasks get canceled because of
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
.
So it seems there is parallelization built into blobClient
, but it's failing still. Additionally, I cannot use https://www.nuget.org/packages/Microsoft.Azure.Storage.DataMovement because it doesn't work with Xamarin Forms
.
推荐答案
如果要将文件分块上传到Azure blob存储,请参考以下代码
If you want to upload file to Azure blob storage in chunk, please refer to the following code
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, 0, 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令牌,请参考以下代码
If you want to use sas token, please refer to the following code
var uri = new Uri($"https://{storageAccountName}.blob.core.windows.net/{containerName}/{blobName}?{sasToken}");
BlockBlobClient blobClient = new BlockBlobClient(uri);
这篇关于Azure存储:BlobClient在上载大文件时不断重置自身的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!