web-dev-qa-db-fra.com

async Task vs async void

Cela peut être une question très stupide, mais j'ai les lignes de codage suivantes qui convertissent les images RAW en BitmapImages:

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

qui appelle cette méthode 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;
}

Lorsque j'utilise async Void Au lieu de async Task Dans ma méthode CreateImageThumbnails, mon application traite les images (29 d'entre elles) environ 11 secondes plus rapidement que async Task. Pourquoi serait-ce?

async voidasync void

tâche asynchroneasync task

L'utilisation de la mémoire utilise beaucoup plus void, mais l'opération est terminée beaucoup plus rapide. J'ai peu de connaissances sur le filetage, c'est pourquoi je pose cette question. Quelqu'un peut-il expliquer pourquoi cela se produit?

J'ai aussi fait des recherches sur quand et quand ne pas utiliser async void, Mais je n'ai pas trouvé de réponse à ma question. (Je n'ai peut-être pas très bien cherché).

Je vous remercie.

16
CareTaker22

Lorsque vous appelez une méthode async void Ou appelez une méthode async Task Sans l'attendre, votre code continuera immédiatement, sans attendre la fin de la méthode. Cela signifie que plusieurs invocations de la méthode peuvent être en cours d'exécution en parallèle, mais vous ne saurez pas quand elles se termineront, ce que vous devez généralement savoir.

Vous pouvez profiter de l'exécution en parallèle comme ceci, tout en étant en mesure d'attendre que toutes les invocations se terminent en en stockant les Tasks dans une collection puis en utilisant await Task.WhenAll(tasks);.

Gardez également à l'esprit que si vous souhaitez exécuter du code en parallèle, vous devez vous assurer que vous pouvez le faire en toute sécurité. Ceci est communément appelé "thread-safety".

6
svick