Azure CloudBlob上的OpenReadAsync返回空流
我有一个azure函数(EventGrid触发器),在blob存储(Data Lake storage Gen2)中创建新blob时触发。 在这个函数中,我需要读取blob并将其反序列化为一个对象(类型已知) 这是我用来获取CloudBlob的方法:Azure CloudBlob上的OpenReadAsync返回空流,azure,azure-functions,azure-blob-storage,azure-eventgrid,azure-data-lake-gen2,Azure,Azure Functions,Azure Blob Storage,Azure Eventgrid,Azure Data Lake Gen2,我有一个azure函数(EventGrid触发器),在blob存储(Data Lake storage Gen2)中创建新blob时触发。 在这个函数中,我需要读取blob并将其反序列化为一个对象(类型已知) 这是我用来获取CloudBlob的方法: public async Task<CloudBlob> GetCloudBlob(Uri uri) { var cloudBlockBlob = new CloudBlob(uri, _storageCredentials);
public async Task<CloudBlob> GetCloudBlob(Uri uri)
{
var cloudBlockBlob = new CloudBlob(uri, _storageCredentials);
if (await cloudBlockBlob.ExistsAsync())
return cloudBlockBlob;
return null;
}
在HandleFile方法中,我调用反序列化异步方法:
var model = await JsonSerializer.DeserializeAsync<RequestModel>(stream);
有趣的是,如果我再次重试这个blob的过程,那么流就会按预期填充
我是否缺少任何等待条件,或者blob是否仍未完全写入存储器?序列化到流会将流保留在末尾,因此,当您要对其进行反序列化时,无需进行反序列化 您需要添加一行,如:
stream.Position = 0;
在序列化之后反序列化之前。尝试将
等待cloudBlockBlob.ExistsAsync()
转换为等待cloudBlockBlob.ExistsAsync().ConfigureAwait(false)
,等待cloudBlob.OpenReadAsync()
转换为等待cloudBlob.OpenReadAsync().ConfigureAwait(false)
,wait\u requestFileHandler.HandleFile(stream,name,prefix,cloudBlob.Uri)
towait\u requestFileHandler.HandleFile(stream,name,prefix,cloudBlob.Uri)。configurewait(false)
和wait JsonSerializer.DeserializeAsync(stream)
towait JsonSerializer.DeserializeAsync(stream)。configurewait(false)
当应用
await
关键字时,它将暂停调用方法并将控制权返回给调用方,直到等待的任务完成。我们可以通过使用ConfigureAwait(false)
避免强制继续/回调到原始上下文。不使用ConfigureAwait(false)
会导致性能问题和不可靠性。因为您没有使用它,流
有时在调用方上下文中,有时在当前上下文中。当前上下文中的一个将为您提供正确的结果。有关详细信息,请访问devblogs.microsoft.com/dotnet/configureawait-faq。您可以为EventGridTrigger函数使用blob输入绑定来获取blob流,请参阅以下代码段:
public static async Task Run(JObject eventGridEvent, Stream body, ILogger log)
{
log.LogInformation($"{eventGridEvent}");
// ...
var model = await System.Text.Json.JsonSerializer.DeserializeAsync<RequestModel>(body);
// ...
await Task.CompletedTask;
}
将
await cloudBlockBlob.ExistsAsync()
转换为await cloudBlockBlob.ExistsAsync().ConfigureAwait(false)
,await cloudBlob.OpenReadAsync()
到await cloudBlob.OpenReadAsync().ConfigureAwait(false)
,await\u requestFileHandler.HandleFile(流、名称、前缀、cloudBlob.Uri)
toawait\u requestFileHandler.HandleFile(流、名称、前缀、cloudBlob.Uri)。ConfigureAwait(false)
和await JsonSerializer.DeserializeAsync(流)
toawait JsonSerializer.DeserializeAsync(流)。ConfigureAwait(false)
。它很可能会工作。@HarshitaSingh MSFT为什么会这样做?你可以深入阅读这篇文章-当应用await
关键字时,它会暂停调用方法并将控制权交还给调用方,直到等待的任务完成。我们可以通过使用ConfigureAwait(false)
避免强制继续/回调到原始上下文。不使用ConfigureAwait(false)
会导致性能问题和不可靠性。因为您没有使用它,流
有时在调用方上下文中,有时在当前上下文中。当前上下文中的一个将为您提供正确的结果。您可以访问了解更多信息。请让我知道,如果这回答了您的问题,我将发布它作为一个答案。
stream.Position = 0;
public static async Task Run(JObject eventGridEvent, Stream body, ILogger log)
{
log.LogInformation($"{eventGridEvent}");
// ...
var model = await System.Text.Json.JsonSerializer.DeserializeAsync<RequestModel>(body);
// ...
await Task.CompletedTask;
}
{
"bindings": [
{
"type": "eventGridTrigger",
"name": "eventGridEvent",
"direction": "in"
},
{
"type": "blob",
"name": "body",
"path": "{data.url}",
"connection": "rk2019dlstg_STORAGE",
"direction": "in"
}
],
"disabled": false
}