【问题标题】:Exception when creating blob asyncronously with Azure Storage - UploadTextAsync使用 Azure 存储异步创建 blob 时出现异常 - UploadTextAsync
【发布时间】:2018-11-01 19:55:42
【问题描述】:

在我们的项目中,我们使用的是 Azure Storage 6.0.0 版本,并且我们正在使用 UploadTextAsync 方法来创建 blob。更新到最新版本后,UploadTextAsync 函数停止工作,现在抛出异常:

“对象引用未设置为对象的实例。”

我尝试了不同的方法来替换它,但都抛出了相同的异常。例如:

byte[] fileBytes = Encoding.UTF8.GetBytes(data);
await lockBlob.UploadFromByteArrayAsync(fileBytes, 0, fileBytes.Length);

我让它工作的唯一方法是更改​​为同步版本:

BlobRequestOptions blobOptions = new BlobRequestOptions
{
         MaximumExecutionTime = TimeSpan.FromSeconds(5),
};
lockBlob.UploadText(data, null, null, blobOptions, null);

我怎样才能使异步版本工作?有解决方法吗?我真的需要异步版本。

UploadText(异步和同步)方法会在 blob 不存在时创建它,如果存在则覆盖它。

为什么它适用于同步版本而不是异步更新?

对于 blob 创建,代码如下:

var container= client.GetContainerReference("lockblobs");
await container.CreateIfNotExistsAsync();
var lockBlob = container.GetBlockBlobReference(data);

【问题讨论】:

标签: c# azure azure-storage azure-blob-storage blobstorage


【解决方案1】:

已解决:

通过 Azure 包内的调用堆栈进行调试后,发现 BlobRequestOptions 中有一个检查,默认情况下 RequireEncryption 和 EncryptionPolicy 之间存在不匹配。

这是 BlobRequestOptions 定义中的罪魁祸首:

internal void AssertPolicyIfRequired()
{
    if (this.RequireEncryption.HasValue && this.RequireEncryption.Value && this.EncryptionPolicy == null)
    {
          throw new InvalidOperationException(SR.EncryptionPolicyMissingInStrictMode);
    }
}

https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Blob/BlobRequestOptions.cs

所以基本上是这样做的:

BlobRequestOptions blobOptions = new BlobRequestOptions
{
    MaximumExecutionTime = TimeSpan.FromSeconds(5),
    ParallelOperationThreadCount = 48,
    RequireEncryption = false
};

await lockBlob.UploadTextAsync(data, null, null, blobOptions, null);

我避免在 AssertPolicyIfRequired 检查中进行检查。所以最重要的是,设置RequireEncryption = false 或将其设置为 true 并定义适当的加密策略。

现在所有 Upload****Async 方法都可以使用。

这是帮助我调试问题的调用堆栈:

{"ClassName":"System.NullReferenceException","Message":"Object reference not set to an instance of an object.","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":"   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.<>c__DisplayClass1d.b__f(Action continuation) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 620
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.BeginUploadFromStreamHelper(Stream source, Nullable`1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, Object state) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 665
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, Object state) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 477
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.BeginUploadFromByteArray(Byte[] buffer, Int32 index, Int32 count, AsyncCallback callback, Object state) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 1146
   at Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.TaskFromVoidApm[T1,T2,T3](Func`6 beginMethod, Action`1 endMethod, T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Util\AsyncExtensions.cs:line 210
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArrayAsync(Byte[] buffer, Int32 index, Int32 count, CancellationToken cancellationToken) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 1204
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArrayAsync(Byte[] buffer, Int32 index, Int32 count) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 1190

【讨论】:

  • 太棒了!您可以接受您的答案供其他人参考。在控制台应用程序中,我无法重现您的问题。 RequireEncryption 默认为 false,如方法备注中所述。一旦我在未定义策略的情况下将其设置为 true,则异常为 Encryption Policy is mandatory when RequireEncryption is set to true. If you do not want to encrypt/decrypt data, please set RequireEncryption to false in request options。是否可能是由您项目中的其他设置/代码引起的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
相关资源
最近更新 更多