How to implement video file streaming in ASP.Net MVC? - c#

I want to implement simple video file streaming.
There is my API controller:
[HttpGet]
[Route("api/VideoContent")]
public HttpResponseMessage GetVideoContent([FromUri] string fileName)
{
if (fileName == null)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
if (Request.Headers.Range != null)
{
try
{
//using (FileStream fileStream = _videoFileProvider.GetFileStream(fileName))
//{
HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
FileStream fileStream = _videoFileProvider.GetFileStream(fileName);
partialResponse.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, new MediaTypeHeaderValue("video/mp4"));
return partialResponse;
//}
}
catch (Exception)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
return new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable);
}
This code is working, but as you see fileStream not disposed. I tried to use using block (commented lines), but this code doesn't work - in debug mode method run without exceptions, but browser shows response with 500 error code.
Where is my mistake? Why I am getting 500 Internal Server Error? How to correctly dispose file stream in my case?

AFAIK, what have you implemented for downloading content without disposing filestream is right.
As you have been using HttpResponseMessage for returning response which is automatically disposed by the framework itself after done with sending response to the client.
This has already been pointed by MSFT guy in comment of another post
If you looks at dispose method of HttpResponseMessage in source code,
protected virtual void Dispose(bool disposing)
{
// The reason for this type to implement IDisposable is
//that it contains instances of types that implement
// IDisposable (content).
if (disposing && !_disposed)
{
_disposed = true;
if (_content != null)
{
_content.Dispose();
}
}
}
You can see _content has been disposed which is of type HttpContent i.e. in your case, object of ByteRangeStreamContent set in the Content property of HttpResponseMessage.
Disposing ByteRangeStreamContent object implemented in following way :
protected override void Dispose(bool disposing)
{
Contract.Assert(_byteRangeContent != null);
if (disposing)
{
if (!_disposed)
{
_byteRangeContent.Dispose();
_content.Dispose();
_disposed = true;
}
}
base.Dispose(disposing);
}
In above Dispose method of ByteRangeStreamContent, you can see that it is disposing itself and disposing _content(in your case FileStream) as well which is stream used for creating ByteRangeStreamContent object.
I strongly believe, your implementation without disposing filestream is correct as disposing starts in sequence when done with sending response to client.

Related

Not disposing stream in .NET Core

Consider ASP.NET Core's ResponseBufferingMiddleware:
public class ResponseBufferingMiddleware
{
private readonly RequestDelegate _next;
public ResponseBufferingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var originalResponseBody = httpContext.Response.Body;
// no-op if buffering is already available.
if (originalResponseBody.CanSeek)
{
await _next(httpContext);
return;
}
var originalBufferingFeature = httpContext.Features.Get<IHttpBufferingFeature>();
var originalSendFileFeature = httpContext.Features.Get<IHttpSendFileFeature>();
try
{
// Shim the response stream
var bufferStream = new BufferingWriteStream(originalResponseBody);
httpContext.Response.Body = bufferStream;
httpContext.Features.Set<IHttpBufferingFeature>(new HttpBufferingFeature(bufferStream, originalBufferingFeature));
if (originalSendFileFeature != null)
{
httpContext.Features.Set<IHttpSendFileFeature>(new SendFileFeatureWrapper(originalSendFileFeature, bufferStream));
}
await _next(httpContext);
// If we're still buffered, set the content-length header and flush the buffer.
// Only if the content-length header is not already set, and some content was buffered.
if (!httpContext.Response.HasStarted && bufferStream.CanSeek && bufferStream.Length > 0)
{
if (!httpContext.Response.ContentLength.HasValue)
{
httpContext.Response.ContentLength = bufferStream.Length;
}
await bufferStream.FlushAsync();
}
}
finally
{
// undo everything
httpContext.Features.Set(originalBufferingFeature);
httpContext.Features.Set(originalSendFileFeature);
httpContext.Response.Body = originalResponseBody;
}
}
}
Link to actual file: https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/ResponseBufferingMiddleware.cs
Why is this not a memory leak? They create a new BufferingWriteStream (https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs), but never dispose of it. Does the HTTP Pipeline automatically dispose of streams after a finished request or something?
This stream is just a wrapper around other stream you pass in its constructor (originalResponseBody in this case). As such - there is no need to dispose it - by itself it does not contain any unmanaged resources it can clear\release, nor does it contain any other disposable components it should dispose, so there is no reason for it to implement IDisposable, but it inherits from class that already implements it. It just proxies all Stream methods (like Read and so on) to the wrapped stream with some additional logic (buffering).

Will disposing a RegistryKey also close it?

As the title says.
Also, the other way around; will closing a RegistryKey dispose it?
I've looked around in all documentation I could find and nothing of this is mentioned anywhere.
It will call the Dispose() method inside of Close(), meaning YES it will be "disposed" and other way around Dispose() will Close() key. System registry keys are never closed. Only keys that are being closed - HKEY_PERFORMANCE_DATA.
.NET source for Close method:
/**
* Closes this key, flushes it to disk if the contents have been modified.
*/
public void Close() {
Dispose(true);
}
.NET source line 220
.NET source for Dispose method:
[System.Security.SecuritySafeCritical] // auto-generated
private void Dispose(bool disposing) {
if (hkey != null) {
if (!IsSystemKey()) {
try {
hkey.Dispose();
}
catch (IOException){
// we don't really care if the handle is invalid at this point
}
finally
{
hkey = null;
}
}
else if (disposing && IsPerfDataKey()) {
SafeRegistryHandle.RegCloseKey(RegistryKey.HKEY_PERFORMANCE_DATA);
}
}
}
.NET source line 227

TcpClient disposed prematurely

I have a problem I cannot seem to figure out, please help. I have created a class to handle an interface to some HW using TcpClient. I want this class to send one last command to the HW before it is destroyed.
To solve this I have implemented IDisposable.Dispose to take care of the sending of the last command and then close the connection. I have also in the destructor made a call to Dispose. This is the Microsoft recommendation as I read it in this article. My code is as follows:
class MyHWInterface : IDisposable
{
~MyHWInterface()
{
Dispose();
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
CloseConnection();
disposed = true;
}
}
private System.Net.Sockets.TcpClient Port = new System.Net.Sockets.TcpClient();
public bool OpenConnection()
{
...
}
private bool SendCommand(string command)
{
var strm = Port.GetStream(); // This throws the exception Cannot access disposed object!
var w = new System.IO.StreamWriter(strm, System.Text.Encoding.ASCII);
var r = new System.IO.StreamReader(strm, System.Text.Encoding.ASCII);
w.WriteLine(command);
w.Flush();
string l = r.ReadLine();
return l == "OK";
}
internal void CloseConnection()
{
try
{
SendCommand("power down now");
}
catch
{
}
finally
{
Port.Close();
}
}
}
My problem is: When my program ends, and my object of MyHWInterface therefore falls out of scope and then gets garbage collected. The destructor is called which tries to send the last command, which fails because somehow my TcpClient is already disposed.
Please tell me why an object which is clearly not yet out of scope is being disposed. And please help with a method that makes sure my last command always will be send without an explicit call to Dispose.
Please tell me why an object which is clearly not yet out of scope is being disposed.
Objects don't have a concept of "scope" as such. At the end of your program, both the TcpClient and the instance of your class are eligible for finalization - and there's no guarantee which will be finalized first. It sounds like the TcpClient is being finalized (and the connection closed) first, hence the issue.
The best fix is not to rely on finalization for this in the first place - remove your own finalizer (realizing that the connection will just be closed at some point if the client doesn't call Dispose) and make sure that you do dispose of everything in an orderly fashion when your program terminates, assuming it's terminated cleanly (i.e. through some path you control).

Calling dispose() on a reference to an IDisposable

I have some code to add attachments to an email. I'm adding them via the Stream overload of the Attachment class constructor. The code to do it looks like this:
List<UploadedDocument> docs = DataBroker.GetUploadedDocs(Convert.ToInt32(HttpContext.Current.Session["offer_id"].ToString()));
//no need to keep this in session
HttpContext.Current.Session["offer_id"] = null;
int counter = 1;
foreach (UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
attach = new Attachment(stream, "Attachment-" + counter.ToString());
message.Attachments.Add(attach);
}
Where doc.doc is a byte array. I want to properly dispose of each attachment and stream, but I can't do it until the message has been sent, so I was thinking about just adding them to a List<Attachment> and List<Stream> and then iterating through and calling dispose.
Something like this:
List<Attachment> attachments;
List<Stream> streams;
//...
foreach(UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
streams.Add(stream);
attach = new Attachment(stream,"Name");
attachments.Add(attach);
message.Attachments.Add(attach);
}
//other processing
emailClient.Send(message);
if(attachments != null)
{
foreach(Attachment attachment in attachments)
{
attachment.Dispose();
}
}
if(streams != null)
{
foreach(MemoryStream myStream in streams)
{
myStream.Dispose();
}
}
But something tells me that won't dispose them properly if there is still a reference floating around that hasn't gotten garbage collected or something. Any thoughts?
The simplest way to handle this is to just call Dispose() on the MailMessage.
MailMessage.Dispose will automatically dispose all attachments, which in turn will close/Dispose() all of the underlying streams.
//other processing
emailClient.Send(message);
message.Dispose(); // Or just wrap this entire block in a using statement
This is already implemented by MailMessage.Dispose method:
protected virtual void Dispose(bool disposing)
{
if (disposing && !this.disposed)
{
this.disposed = true;
if (this.views != null)
{
this.views.Dispose();
}
if (this.attachments != null)
{
this.attachments.Dispose();
}
if (this.bodyView != null)
{
this.bodyView.Dispose();
}
}
}
Just wrap usage of MailMessage into using statement and all resources, used by the MailMessage will be released after you leave using block:
using(var message = new MailMessage(from, to))
{
foreach (UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
attach = new Attachment(stream, "Attachment-" + counter.ToString());
message.Attachments.Add(attach);
}
emailClient.Send(message);
}
There are already replies on right way (MailMessage.Dispose), so on "dispose them properly if there is still a reference...":
Dispose will (expected too) release resources at the moment of the call irrespective of who have references to the object. One of common approaches is to also have inner flag in the object that implements Dispose that will block any further calls by throwing "Object Disposed" exception.
You can (and probably already did) observe this behavior if you Dispose your streams before done using them. I.e. in your mail case you may try to dispose stream immediately after message.Attachments.Add(attach); which most likely will lead to "stream disposed" exception later during Send call.
Note that there are some objects like MemoryStream that have specially defined behavior after Dispose. I.e. MemoryStream blocks all calls except ToArray/Lenght/GetBuffer since one of the main purposes of this class is to give you resulting byte array of a stream. As side effect MemoryStream's Dispose is essentially only setting flag to block other calls (which is fine as this class does not have any native resources).

Should I call Close() or Dispose() for stream objects?

Classes such as Stream, StreamReader, StreamWriter etc implements IDisposable interface. That means, we can call Dispose() method on objects of these classes. They've also defined a public method called Close(). Now that confuses me, as to what should I call once I'm done with objects? What if I call both?
My current code is this:
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
writer.Close();
}
reader.Close();
}
}
As you see, I've written using() constructs, which automatically call Dispose() method on each object. But I also call Close() methods. Is it right?
Please suggest me the best practices when using stream objects. :-)
MSDN example doesn't use using() constructs, and call Close() method:
How to: Download Files with FTP
Is it good?
A quick jump into Reflector.NET shows that the Close() method on StreamWriter is:
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
And StreamReader is:
public override void Close()
{
this.Dispose(true);
}
The Dispose(bool disposing) override in StreamReader is:
protected override void Dispose(bool disposing)
{
try
{
if ((this.Closable && disposing) && (this.stream != null))
{
this.stream.Close();
}
}
finally
{
if (this.Closable && (this.stream != null))
{
this.stream = null;
/* deleted for brevity */
base.Dispose(disposing);
}
}
}
The StreamWriter method is similar.
So, reading the code it is clear that that you can call Close() & Dispose() on streams as often as you like and in any order. It won't change the behaviour in any way.
So it comes down to whether or not it is more readable to use Dispose(), Close() and/or using ( ... ) { ... }.
My personal preference is that using ( ... ) { ... } should always be used when possible as it helps you to "not run with scissors".
But, while this helps correctness, it does reduce readability. In C# we already have plethora of closing curly braces so how do we know which one actually performs the close on the stream?
So I think it is best to do this:
using (var stream = ...)
{
/* code */
stream.Close();
}
It doesn't affect the behaviour of the code, but it does aid readability.
No, you shouldn't call those methods manually. At the end of the using block the Dispose() method is automatically called which will take care to free unmanaged resources (at least for standard .NET BCL classes such as streams, readers/writers, ...). So you could also write your code like this:
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
}
The Close() method calls Dispose().
The documentation says that these two methods are equivalent:
StreamReader.Close: This implementation of Close calls the Dispose method passing a true value.
StreamWriter.Close:
This implementation of Close calls the Dispose method passing a true value.
Stream.Close: This method calls Dispose, specifying true to release all resources.
So, both of these are equally valid:
/* Option 1, implicitly calling Dispose */
using (StreamWriter writer = new StreamWriter(filename)) {
// do something
}
/* Option 2, explicitly calling Close */
StreamWriter writer = new StreamWriter(filename)
try {
// do something
}
finally {
writer.Close();
}
Personally, I would stick with the first option, since it contains less "noise".
For what it's worth, the source code for Stream.Close explains why there are two methods:
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup now.
In short, Close is only there because it predates Dispose, and it can't be deleted for compatibility reasons.
This is an old question, but you can now(C# 8.0) write using statements without needing to block each one. They will be disposed of in reverse order when the containing block is finished.
using var responseStream = response.GetResponseStream();
using var reader = new StreamReader(responseStream);
using var writer = new StreamWriter(filename);
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using
On many classes which support both Close() and Dispose() methods, the two calls would be equivalent. On some classes, however, it is possible to re-open an object which has been closed. Some such classes may keep some resources alive after a Close, in order to permit reopening; others may not keep any resources alive on Close(), but might set a flag on Dispose() to explicitly forbid re-opening.
The contract for IDisposable.Dispose explicitly requires that calling it on an object which will never be used again will be at worst harmless, so I would recommend calling either IDisposable.Dispose or a method called Dispose() on every IDisposable object, whether or not one also calls Close().
Just to complement other answers, as of C# 8.0, you don't need to open a block of code just to use an using statement
if (...)
{
using FileStream f = new FileStream(#"C:\users\jaredpar\using.md");
// statements
}
// Equivalent to
if (...)
{
using (FileStream f = new FileStream(#"C:\users\jaredpar\using.md"))
{
// statements
}
}
docs:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using

Categories

Resources