What is different with PushStreamContent between web api & web api 2?

This is a known issue with the C# spec. Check out this SO question - Compiler Ambiguous invocation error - anonymous method and method group with Func<> or Action

When we introduced this overload that returns a Task, we did realize that it is a source level breaking change (though it doesn't break binary compatibility). We still went ahead with the change as not fixing it would cause more issues.

And regarding how to fix it, you have two options -

  1. As Kiran suggested earlier, you can use the anonymous method syntax so that the compiler picks the right overload for you.
  2. You can use an explicit cast, like below,

    response.Content = new PushStreamContent((Action)video.WriteToStream, new MediaTypeHeaderValue("video/"+ext));

BTW, be careful with that async void method. I suggest you to change its signature to

public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context)

I am not sure if this is a bug in Web API, we will investigate into it. Meanwhile you can try the following workaround:

response.Content = new PushStreamContent(async (Stream outputStream, HttpContent content, TransportContext context) =>
{
    try
    {
        var buffer = new byte[65536];

        using (var video = File.Open(filename, FileMode.Open, FileAccess.Read))
        {
            var length = (int)video.Length;
            var bytesRead = 1;

            while (length > 0 && bytesRead > 0)
            {
                bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length));
                await outputStream.WriteAsync(buffer, 0, bytesRead);
                length -= bytesRead;
            }
        }
    }
    finally
    {
        outputStream.Close();
    }
});

Note: I made another change(removed the catch block) to the code to allow exceptions to propagate. This is so that your clients know that some error happened at the service otherwise they would assume everything went smooth.


The signature of the PushStreamContent constructor changed. Its onStreamAvailable parameter is an Action or Func generic type. The trouble is that the compiler doesn't know which type to bind to.

So to resolve the error cast the streamAvailableHandler as an Action:

response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)streamAvailableHandler);

And the handler method would be:

private void streamAvailableHandler(Stream stream, HttpContent content, TransportContext context) {
  ...write to stream
}