aamir sajjad
aamir sajjad

Reputation: 3039

Mixing Async and Sync in same HTTP request ASP.NET Core C#

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

Answers (3)

Gabriel Luci
Gabriel Luci

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

zmbq
zmbq

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

n234
n234

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:

sync over async

async over sync

Upvotes: 2

Related Questions