Search code examples
azure-functionsazure-function-async

Azure V4 function - unable to get multi-response output binding to work for async function


I am working on an azure v4 function running in dotnet-isolated mode using a multiple response (HttpResponseData and Cosmos DB Output binding)

The code worked when it was called synchronously, recently I started getting an error saying synchronous calls are not allowed.

The issue I have is when I change the return type to be async task, it returns the HttpResponseData to the client as expected but does not write out to the CosmosDB.

In the log I can see the following error:

System.ObjectDisposedException: IFeatureCollection has been disposed

Updated Error info. It is returning status 500 with the following (abbreviated) detail:

System.ObjectDisposedException: IFeatureCollection has been disposed.

Object Name 'Collection'

at Microsoft.Azure.Function.Worker.RPC.RpcExtensions.ToRpcHttpSync (.NetWorker.Grpc\RpcExtensions.cs)

Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request)

My MultiReponse class is defined as:

public class MultiResponse {
    [CosmosDBOutput(databaseName:.....]  // Response 1 gets written out to cosmosdb
    public MyDBRecord item {get;set;}    // A class with three public string properties

    public HttpResponseData httpResponse {get;set;}  // Response2 goes back to the client
}

My Azure function had the following definition.

public MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData req) 

I basically changed the MultiResponse to async Task< MultiResponse >. The routine that prepares the response is.

MultiResponse resp = new MultiResponse
{
    HttpResponse = req.CreateResponse(statusCode),
    Item = myDbRecord  // Basically a class with 3 public string properties.
};

 resp.HttpResponse.Headers.Add("Content-Type", "text/plain; charset=utf-8");
 await resp.HttpResponse.WriteStringAsync(JsonConvert.SerializeObject(myDbRecord));

 return resp;

I am wondering if I need to change the output binding or something to handle the change to being async.


Solution

  • Just an update.

    To get it working I needed to remove the async keyword and also any await methods. I still needed to keep the Task as the return type.

    Also, any awaitable calls in the method body needed to be changed to use the Task<Response> functionAsync() calling style.