Reputation: 3039
Is it bad practice to mix async and sync call in same asp.net core api call
For example in following code
Method CropBlackBroderOfAnImageAsync is an Async Method
On the other hand SaveImageForProcessing(file, sourceFolderPath); is Sync Method
Reason: that I am calling SaveImageForProcessing synchronously that I want use the result of it to execute the code in CropBlackBroderOfAnImageAsync
The complete code repo
code reviews are welcome: https://github.com/aamir-poswal/ImageCropApp/
public async Task<(string sourceFolderPath, string destinationFolderPath)> CropBlackBorderOfAnImage(IFormFile file)
{
var extension = Path.GetExtension(file.FileName);
var newFileName = Guid.NewGuid().ToString();//Create a new Name for the file due to security reasons.
var fileNameSource = newFileName + extension;
var sourceFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Source", fileNameSource);
var fileNameDestination = newFileName + "Result" + extension;
var destinationFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Destination", fileNameDestination);
SaveImageForProcessing(file, sourceFolderPath);
await _imageCropBlackBroderService.CropBlackBroderOfAnImageAsync(sourceFolderPath, destinationFolderPath);
return (sourceFolderPath, destinationFolderPath);
}
private void SaveImageForProcessing(IFormFile file, string path)
{
using (var bits = new FileStream(path, FileMode.Create))
{
file.CopyTo(bits);
}
}
Upvotes: 1
Views: 1955
Reputation: 41008
Reason: that I am calling SaveImageForProcessing synchronously that I want use the result of it to execute the code in CropBlackBroderOfAnImageAsync
I think you misunderstand what asynchronous means. When code runs asynchronously, it means that the current thread is freed to do other things while it is waiting. It might be helpful to read the article Asynchronous programming with async and await. It has a very helpful illustration about cooking breakfast.
It sounds like you believe that running asynchronous means that the code will run somewhere else at the same time that the rest of your code is running. That's called "parallel".
The purpose of async
and await
is to make it easy to start asynchronous tasks and come back to them when you're ready for the results. In your case, since you want the result right away, you can make SaveImageForProcessing
asynchronous, use CopyToAsync
and await
it. Then you can use the result right away.
Because you use await
, when you get to the line calling CropBlackBroderOfAnImageAsync
, you are guaranteed that SaveImageForProcessing
has entirely completed.
public async Task<(string sourceFolderPath, string destinationFolderPath)> CropBlackBorderOfAnImage(IFormFile file)
{
var extension = Path.GetExtension(file.FileName);
var newFileName = Guid.NewGuid().ToString();//Create a new Name for the file due to security reasons.
var fileNameSource = newFileName + extension;
var sourceFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Source", fileNameSource);
var fileNameDestination = newFileName + "Result" + extension;
var destinationFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Destination", fileNameDestination);
await SaveImageForProcessing(file, sourceFolderPath);
await _imageCropBlackBroderService.CropBlackBroderOfAnImageAsync(sourceFolderPath, destinationFolderPath);
return (sourceFolderPath, destinationFolderPath);
}
private async Task SaveImageForProcessing(IFormFile file, string path)
{
using (var bits = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(bits);
}
}
Upvotes: 2
Reputation: 39039
Yes, it is bad practice. If you use a long synchronous operation in your asynchronous code, you're going to freeze all the other asynchronous code as well. The reason for this is that asynchronous code usually runs in one thread. If that thread is busy waiting on a long operation, it can't handle other asynchronous code.
Instead, just use CopyToAsync
, and turn your SaveImageForProcessing
to an async function as well.
Upvotes: 3
Reputation: 249
This all depends on your application. It's totally fine to invoke a synchronous function inside of an async function. Though, you might be leaving some performance on the table. Though, if you are already doing things in an async manner, in an async function, you might as well use the async file IO methods. The code in the async function can still be asynchronous, and still execute in the correct order (which seems to be your concern), you would just await
the results and use them in later lines of code.
The bigger issue is attempting to mask an async
call to make it seem sync
or vice versa.
You might look at these posts:
Upvotes: 2