Jaka jest różnica między QueueUserWorkItem () i BeginInvoke (), dla wykonywania czynności asynchronicznych bez wymaganych typów zwrotów

Kontynuując moje pytanie BeginInvoke () / EndInvoke (), czy istnieją poważne różnice w wydajności / cokolwiek innego między delegatem.BeginInvoke () i używanie QueueUserWorkItem () do asynchronicznie wywoływania delegata?

Author: endian, 2009-02-10

6 answers

Http://blogs.msdn.com/cbrumme/archive/2003/07/14/51495.aspx

Says:

" zaskakujący jest fakt, że jest to również dlaczego delegować.BeginInvoke / EndInvoke są tak powolne w porównaniu do równoważne techniki, takie jak ThreadPool.QueueUserWorkItem (lub UnsafeQueueUserWorkItem jeśli zrozumieć konsekwencje dla bezpieczeństwa i chcą być naprawdę skuteczni). Na ścieżka kodowa dla BeginInvoke / EndInvoke szybko zamienia się w wspólny przekaz kod przetwarzania generał remoting pathway."

 18
Author: Konstantin Savelev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-26 13:15:08

Najważniejsze, o czym myślę, to to, że musisz użyć typu WaitCallback delegate, który wygląda na skomplikowany, jeśli masz już SomeRandomDelegate instancję i niektóre args. Dobrą wiadomością jest to, że możesz to naprawić za pomocą zamknięcia: {]}

ThreadPool.QueueUserWorkItem(
    delegate { someDelegate(arg1, arg2); }
);

Ten wzorzec zapewnia również odpowiednie silne pisanie w czasie kompilacji(w przeciwieństwie do przekazywania ARG stanu object do QueueUserWorkItem i odlewania go w metodzie docelowej). Wzorzec ten może być również użyty podczas bezpośredniego wywoływania metod:

ThreadPool.QueueUserWorkItem(
    delegate { SomeMethod(arg1, arg2); }
);

Oczywiście, bez ekwiwalentu EndInvoke nie można również uzyskać wartości zwracanej z powrotem, chyba że wywołasz metodę / wywołasz Zdarzenie / etc na końcu metody... w związku z tym należy uważać na obsługę wyjątków .

 22
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:32:13

EndInvoke() ma użyteczne, ale rzadko wspominane zachowanie - ponownie sprawdza wszystkie nieobsługiwane wyjątki, które delegat wygenerował w kontekście oryginalnego wątku, dzięki czemu można przenieść logikę przetwarzania WYJĄTKÓW do głównego kodu.

Ponadto, jeśli twój delegat ma parametry out / ref, zostaną one dodane do podpisu EndInvoke (), umożliwiając uzyskanie ich po zakończeniu wykonywania metody.

 15
Author: IlyaP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-18 17:41:36

Jeśli zadzwonisz do ThreadPool.QueueUserWorkItem, wyjątki podniesione w elemencie pracy będą nieobsługiwane w wątku tła(chyba że wyraźnie je złapiesz). W. Net 2 i nowszych spowoduje to zakończenie AppDomain.

Jeśli zadzwonisz do delegata.BeginInvoke() wtedy wyjątki są kolejkowane do ponownego wyrzucenia po wywołaniu EndInvoke (). Jeśli nigdy nie wywołasz endinvoke (), to wyjątki są w zasadzie "wyciekiem" pamięci (tak jak każdy inny stan nie wydany przez operację asynchroniczną).

 4
Author: piers7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-23 00:36:23

Nie powinno być żadnej dużej różnicy, myślę również, że wygenerowany BeginInvoke/EndInvoke dla delegata używa puli wątków do wykonania.

 -1
Author: Maghis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-10 15:34:40

Nie powinno być żadnej różnicy w wydajności, ponieważ oba delegują.BeginInvoke i ThreadPool.QueueUserWorkItem zostanie uruchomiony na wątku puli wątków.

Największa różnica polega na tym, że jeśli wywołujesz BeginInvoke, jesteś zobowiązany do wywołania EndInvoke w pewnym momencie. Natomiast ThreadPool.QueueUserWorkItem jest "fire and forget". To ma zalety i wady. Zaletą jest to, że możesz o tym zapomnieć. Wadą jest to, że nie masz możliwości poznania, chyba że dodasz własne mechanizm synchronizacji/powiadamiania po zakończeniu zadania.

 -1
Author: Jim Mischel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-10 15:36:00