Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core Async File Result

In ASP.Net Core the reccommended way for returning files is to gain access through the PhysicalFileProvider this provides additional security including scoping all paths to a directory and its children. Currently my entire application is Async and I would like for all of my methods to remain so.

public static string BASE_PATH = Path.GetTempPath();
public static string lastSavedFilePath = @"C:\Users\MyUser\AppData\Local\Temp\MyPicture.png"

[HttpGet("{id}")]
public async Task<FileResult> GetFileById(int id)
{
    //provides access to the physical file system, scoping all paths to a directory and its children
    IFileProvider provider = new PhysicalFileProvider(BASE_PATH);
    var fileInfo = provider.GetFileInfo(lastSavedFilePath);
    var fileStream = fileInfo.CreateReadStream();
    this._contentTypeProvider.TryGetContentType(lastSavedFilePath, out var mimeType);
    return File(fileStream, mimeType, "ProfilePicture.png");
}

Edit It turns out obtaining the file through the PhysicalFileProvider is not what I want to be async, I really want the Stream to be read async.

How Can I assure that when Calling my File Operation it will read my stream Async?

like image 334
johnny 5 Avatar asked Apr 03 '18 12:04

johnny 5


People also ask

Should .NET core API be async?

ASP.NET Core apps should be designed to process many requests simultaneously. Asynchronous APIs allow a small pool of threads to handle thousands of concurrent requests by not waiting on blocking calls. Rather than waiting on a long-running synchronous task to complete, the thread can work on another request.

What is FileContentResult?

FileContentResult. Represents an ActionResult that when executed will write a binary file to the response. FileStreamResult. Represents an ActionResult that when executed will write a file from a stream to the response.

What is asynchronous file?

Asynchronous operations enable you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in a Windows 8.

Should I use async EF core?

Generally speaking, if there are asynchronous APIs, then you should use them for new code. Asynchronous code frees up the calling thread. If your application is a GUI application, this can free up the UI thread; if your application is a server application, this can free up threads to handle other requests.


1 Answers

PhysicalFileProvider is perfectly capable of reading files async. GetFileInfo returns information about file, there is nothing that should be done async here. It's similar to new FileInfo("path").

CreateReadStream obtains handle to target file, it's similar to File.OpenRead(). Again - nothing should be async here, and it's not whether you are using PhysicalFileProvider or not.

When you have file stream - you can read it asynchronously as usual (ReadAsync and so on), doesn't matter how you obtained it. In fact, PhysicalFileProvider.CreateReadStream even opens file with correct flags (FileOptions.Asynchronous), making that stream perfect for asynchronous access (and not good for non-async access).

In your case though you don't need to read that file stream yourself. You correctly return it with

return File(fileStream, mimeType, "ProfilePicture.png");

This will already read and write that file to http response stream asynchronously for you. That's because all ActionResults, including FileStreamResult which you return, has Task ExecuteAsync method to actually execute that result. Asp.net will do await yourFileResult.ExecuteAsync() for you, and that ExecuteAsync will copy file stream to http response asynchronously.

So in short - just make your signature

public FileResult GetFileById(int id)

and you will be fine. What should be done asynchronously is done asynchrnously in this code already.

like image 148
Evk Avatar answered Sep 20 '22 11:09

Evk