如何正确处理“"提交的块数不能超过50,000个块的最大限制。"执行CloudAppendBlob.AppendTextAsync?
时出现异常我目前有以下代码:
private async Task MessageLogger()
{
string messages = "";
while (true)
{
// Check if a new log file should be created
if (DateTime.UtcNow.Day != _logCreatedUtc.Day)
{
// Create a new log file
await CreateNewLogAsync();
}
if (_messageQueue.Count == 0 && messages.Length == 0)
{
await Task.Delay(50);
continue;
}
int n = 0;
while ((this._messageQueue.Count > 0) && (n < 50))
{
string message;
if (this._messageQueue.TryPeek(out message))
{
messages += message;
this._messageQueue.TryDequeue(out message);
n++;
}
}
try
{
// Append messages to Azure Blob
await _appendBlob.AppendTextAsync(messages);
messages = "";
}
catch (Microsoft.WindowsAzure.Storage.StorageException exception)
when(exception.RequestInformation.HttpStatusCode == 404)
{
// Log file was deleted. Create a new log file
await CreateNewLogAsync();
}
catch (Exception exception)
{
LogException("Exception from CloudAppendBlob.AppendTextAsync", exception);
await Task.Delay(1000);
}
}
}
我的代码中有时会因为通用异常处理程序而记录以下类型的异常:
01.04.2018 22:17:03.030 - <<EXCEPTION>>: Exception from CloudAppendBlob.AppendTextAsync
01.04.2018 22:17:03.044 - <<EXCEPTION>>: Type =<System.AggregateException> Message =<One or more errors occurred. (One or more errors occurred. (The committed block count cannot exceed the maximum limit of 50,000 blocks.))> InnerException.Message=<One or more errors occurred. (The committed block count cannot exceed the maximum limit of 50,000 blocks.)>
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.<Dispose>b__8_0()
at Microsoft.WindowsAzure.Storage.Core.Util.CommonUtility.RunWithoutSynchronizationContext(Action actionToRun)
at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at Microsoft.WindowsAzure.Storage.Blob.CloudAppendBlob.<UploadFromStreamAsyncHelper>d__34.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Infrastructure.Logging.AzureBlob.Logger.<MessageLogger>d__24.MoveNext() in /opt/vsts/work/1/s/Infrastructure/Logging/Infrastructure.Logging.AzureBlob/Logger.cs:line 183
异常处理程序如何捕获这种错误?我想为它添加一个特定的处理程序。
我试图查看调试器,但看起来很奇怪:
异常变量看起来像&#34; null&#34;在调试器中,但实际上它没有,它被记录正确。
答案 0 :(得分:1)
我与产品团队进行了核实,他们建议实施并使用AccessConditions进行块附加,以避免发生异常:
/// <summary>
/// Gets or sets a value for a condition that specifies the maximum size allowed for an append blob when a new block is committed. The append
/// will succeed only if the size of the blob after the append operation is less than or equal to the specified size.
/// </summary>
/// <value>The maximum size in bytes, or <c>null</c> if no value is set.</value>
/// <remarks>This condition only applies to append blobs.</remarks>
public long? IfMaxSizeLessThanOrEqual
基本上你将检查块的数量,并根据条件,你可以开始一个新的blob追加(如果达到最大值),或继续追加。
这两个会有所帮助:
x-ms-blob-condition-maxsize :客户端可以使用此标头确保追加操作不会将blob大小增加到超出预期的最大大小(以字节为单位)。如果条件失败,请求将失败并出现MaxBlobSizeConditionNotMet错误(HTTP状态代码412 - Precondition Failed)。
x-ms-blob-condition-appendpos 可选条件标头,仅用于附加块操作。一个数字,指示要比较的字节偏移量。仅当追加位置等于此数字时,追加阻止才会成功。如果不是,则请求将因AppendPositionConditionNotMet错误而失败(HTTP状态代码412 - Precondition Failed)。
<强>来源:** https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/AccessCondition.cs **
https://docs.microsoft.com/en-us/rest/api/storageservices/append-block
答案 1 :(得分:0)
您的异常包含在AggregateException中。这就是你打开和处理它的方法:
catch (Exception exception)
{
ExtractStorageError(exception);
}
。 。
private static string ExtractStorageError(Exception ex) {
while (ex != null && !(ex is StorageException))
{
ex = (ex.InnerException != null) ? ex.InnerException.GetBaseException() : ex.InnerException;
}
if (ex is StorageException)
{
StorageException se = ex as StorageException;
if(ste.RequestInformation.ExtendedErrorInformation != null)
return se.RequestInformation.ExtendedErrorInformation.ErrorCode;
}
return null;
}