Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async Task vs async void

This might be a very stupid question, but I have the following lines of coding that convert RAW images to BitmapImages:

public async void CreateImageThumbnails(string imagePath, int imgId)
{
    await Task.Run(() => controlCollection.Where(x => x.ImageId == imgId)
                   .FirstOrDefault()
                   .ImageSource = ThumbnailCreator.CreateThumbnail(imagePath));
}

which calls this method CreateThumbnail()

public static BitmapImage CreateThumbnail(string imagePath)
{
    var bitmap = new BitmapImage();

    using (var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
    {
        bitmap.BeginInit();
        bitmap.DecodePixelWidth = 283;
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = stream;
        bitmap.EndInit();
    }

    bitmap.Freeze();

    GC.WaitForPendingFinalizers();
    GC.Collect();

    return bitmap;
}

When using async Void instead of async Task in my CreateImageThumbnails method, my application processes the images (29 of them) about 11 seconds faster than async Task. Why would this be?

async void async void

async task async task

The memory usage is much more using void, but the operation is completed much quicker. I have little knowledge of threading, this is why I am asking this question. Can someone please explain why this is happening?

Also I have done some research on when and when not to use async void, but I could not find an answer to my question. (I might just not have searched very well).

Thank you.

like image 912
CareTaker22 Avatar asked Jul 03 '17 10:07

CareTaker22


People also ask

What is the difference between async void and async task?

A Task returning async method can be awaited, and when the task completes, the continuation of the task is scheduled to run. A void returning async method cannot be awaited; it is a "fire and forget" method. It does work asynchronously, and you have no way of telling when it is done.

Can we use async void in C#?

In theory, C# developers working with async/await do not need to use or implement callbacks, but occasionally you may need to work with a library that does not make use of async/await and instead requires you to provide a callback method.

How does async void work?

async void has the same semantics as async Task , except for exceptions. An async void method will capture the current SynchronizationContext at the beginning of the method, and any exceptions from that method will be captured and raised directly on that captured context.

Is async but does not return a task?

Async methods that don't contain a return statement or that contain a return statement that doesn't return an operand usually have a return type of Task. Such methods return void if they run synchronously.


1 Answers

When you call an async void method, or call an async Task method without awaiting it (if the called method contains an await, so it doesn't block), your code will continue right away, without waiting for the method to actually complete. This means that several invocations of the method can be executing in parallel, but you won't know when they actually complete, which you usually need to know.

You can take advantage of executing in parallel like this, while also being able to wait for all the invocations to complete by storing the Tasks in a collection and then using await Task.WhenAll(tasks);.

Also keep in mind that if you want to execute code in parallel, you have to make sure it's safe to do it. This is commonly called "thread-safety".

like image 136
svick Avatar answered Oct 14 '22 01:10

svick