Azure CloudBlob上的OpenReadAsync返回空流

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);

我有一个azure函数(EventGrid触发器),在blob存储(Data Lake storage Gen2)中创建新blob时触发。 在这个函数中,我需要读取blob并将其反序列化为一个对象(类型已知)

这是我用来获取CloudBlob的方法:

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)
to
wait\u requestFileHandler.HandleFile(stream,name,prefix,cloudBlob.Uri)。configurewait(false)
wait JsonSerializer.DeserializeAsync(stream)
to
wait 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)
to
await\u requestFileHandler.HandleFile(流、名称、前缀、cloudBlob.Uri)。ConfigureAwait(false)
await JsonSerializer.DeserializeAsync(流)
to
await 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
}