2017-07-03 62 views
12

To może być bardzo głupie pytanie, ale mam następujące wiersze kodowania, które przekształcają obrazów RAW do BitmapImages:asynchroniczny Zadanie vs asynchronicznym pustce

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

który wywołuje tę metodę 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; 
} 

Podczas korzystania z metody async Void zamiast async Task w mojej metodzie CreateImageThumbnails moja aplikacja przetwarza obrazy (29 z nich) około 11 sekund szybciej niż async Task. Dlaczego miałoby to być?

asynchroniczny void async void

asynchroniczny zadanie async task

Wykorzystanie pamięci jest znacznie bardziej użyciu void, ale operacja jest zakończona znacznie szybciej. Mam małą wiedzę na temat wątków, dlatego właśnie zadaję to pytanie. Czy ktoś może wyjaśnić, dlaczego tak się dzieje?

Również zrobiłem pewne badania na temat kiedy i kiedy nie używać async void, ale nie mogłem znaleźć odpowiedzi na moje pytanie. (Mogłem po prostu nie przeszukiwać bardzo dobrze).

Dziękuję.

+1

Może to pomoże: https://stackoverflow.com/questions/12144077 –

+0

'async void' to ogień i zapomnij, więc nic nie śledzi operacji asynchronicznej (lub nawet upewnia się, że działa całkowicie), podczas gdy' async Zadanie "faktycznie utrzymuje ścieżkę, na którą można czekać. – poke

+0

Czy oczekujesz na zadanie, gdy używasz zadania? – Magnus

Odpowiedz

6

Po wywołaniu metody async void lub wywołaniu metody async Task, nie czekając na nią, Twój kod będzie kontynuowany od razu, bez czekania na faktyczną realizację metody. Oznacza to, że kilka wywołań metody może wykonywać równolegle, ale nie będziesz wiedzieć, kiedy faktycznie się ukończy, co zwykle musisz znać.

można wykorzystać do wykonania równolegle jak ta, będąc jednocześnie w stanie czekać na wszystkie wezwania do uzupełnienia przez przechowywania Task S w kolekcji a następnie za pomocą await Task.WhenAll(tasks);.

Pamiętaj też, że jeśli chcesz wykonywać kod równolegle, upewnij się, że jest to bezpieczne. Jest to powszechnie nazywane "bezpieczeństwem gwintów".