2009-12-10 11 views
12

Potrzebuję wiedzieć, czy wywołania Control.BeginInvoke i Control.Invoke będą wykonywane w kolejności, w której są wywoływane.Czy wielokrotne Control.BeginInvoke/Invoke wywołań wykonać w kolejności?

Mam następujący scenariusz:

  1. UI wątek jest zablokowany
  2. WCF wątek wywołuje Control.BeginInvoke
  3. WCF wątek wywołuje Control.Invoke (ewentualnie BeginInvoke ponownie)
  4. UI wątek jest odblokowany
  5. ??

Gwarantuje się, że kolejność wykonywania w kroku 1-4 będzie w podanej kolejności (technicznie nie można zagwarantować, że zamówienie jest takie, ale pytanie, które mam, dotyczy tylko zamówienia, jak pokazano).

Mam pytanie, czy istnieje szansa, że ​​wywołanie Invoke/BeginInvoke w kroku 3 zostało wykonane przed wywołaniem BeginInvoke w kroku 2?

Prosimy również nie komentować blokowania wątku interfejsu użytkownika.

Odpowiedz

10

W twoim przypadku krok 2 zawsze zostanie wykonany przed krokiem 3. BeginInvoke na wątku UI zostanie wykonane w kolejności, w której zostało umieszczone w kolejce.

Wątek interfejsu użytkownika jest w rzeczywistości pompą komunikatów, ma jedną kolejkę komunikatów z tylko jednym wątkiem, który ją zużywa, więc gwarantuje się, że elementy pracy będą wykonywane w kolejności, w jakiej były w kolejce.

Jest z Delegate.BeginInvoke, że kolejność wykonywania może być niesekwencyjna.

+0

Więc komentarz stwierdzający, że synchroniczne wywołania Invoke mogą być wykonywane przed asynchronicznym wywołaniem BeginInvoke nie ma zastosowania dla Control.BeginInvoke, ale dotyczyłoby Delegate.BeginInvoke? Czy możesz podać link, który to wyjaśnia? – cornergraf

+0

Twoje oświadczenie jest poprawne. Dodałem krótkie wyjaśnienie pompy wiadomości UI w odpowiedzi, co dziwne, nie mogę znaleźć oficjalnego źródła stwierdzającego to. –

+0

Ok, dzięki. W ogóle wiem o MessagePump, ale myślałem, że wywołania BeginInvoke/Invoke mogą potencjalnie mieć specjalne zachowanie z jakiegokolwiek powodu i chciałem być pewny. – cornergraf

0

Za mało informacji, aby uzyskać dobrą odpowiedź. Wątek interfejsu użytkownika jest zablokowany, dlatego kroki 2 i 3 muszą być uruchomione na innym wątku. Jeśli nie ma synchronizacji między tymi dwoma, to w jaki sposób możemy poznać jakiekolwiek zamówienie?

Thread 1  Thread 2      Thread 3   Thread 4 
Block UI  Calls BeginInvoke    
Unblock UI  Calls Invoke or BeginInvoke BeginInvoke runs BeginInvoke runs 

Masz dużo zbieżność dzieje, ale z tego co opisałeś, nie ma możliwy sposób możemy Ci co możliwe nastąpi uporządkowania powiedzieć, brakuje mówiąc „wszystko”. Nie możemy nawet powiedzieć, że wywołania BeginInvoke nie będą miały miejsca, zanim wątek interfejsu użytkownika zostanie zablokowany lub po odblokowaniu wątku interfejsu użytkownika.

+0

Cóż, kolejność kroków 1-4 jest gwarantowana w tej kolejności. Pytanie tylko, czy zagwarantuje to również kolejność wykonywania wezwań BeginInvoke/Invoke w krokach 3 i 4. Aktualizuję pytanie, aby było to bardziej jasne. – cornergraf

+0

Ahhh, edycja, która stwierdza, że ​​to 'Control.BeginInvoke' i' Control.Invoke' zmienia się bardzo. Cieszę się, że ktoś był w stanie to dla ciebie ukryć. :) –

+0

Tak, i ponownie zdałem sobie sprawę z tego, jak bardzo ktoś bierze pewne informacje za pewnik podczas dyskusji z innymi. Postaram się być bardziej precyzyjny w przyszłości. Dziękuję za odpowiedź. – cornergraf

3

Wywołania BeginInvoke są umieszczane w kolejce w wątku docelowym (ponieważ są wysyłane w kolejności przybycia).

Połączenia synchroniczne w wątku WCF (krok 3) mogą być wykonywane przed wywołaniami asynchronicznymi (krok 2) wykonanymi z tego wątku.

+0

OK, wielkie dzięki. Czy mógłbyś mieć źródło tego stwierdzenia? Próbowałem znaleźć coś konkretnego w Google, ale bez powodzenia do tej pory. – cornergraf

0

Nie ma szans, aby można było założyć, że jeśli istnieje pewna zależność między tymi dwoma połączeniami, oznacza to, że oczekują na semafor i wykonują zależny kod, gdy oba są zakończone.

Jeśli powodem, dla którego wykonujesz dwa połączenia jednocześnie, nie jest wydajność, prawdopodobnie po prostu wykonam drugie połączenie w wywołaniu zwrotnym pierwszego (znacznie ułatwia debugowanie).

+0

w rzeczywistości, kroki 3 i 4 mogą być zamienione, ale jeśli są one Wiem, że (oczywiście) krok 2 będzie wykonaj najpierw. Dlatego moje pytanie ma znaczenie tylko w przypadku, gdy kolejność wykonania jest dokładnie taka, jak przedstawiono, i dlatego tak to sformułowałem – cornergraf

Powiązane problemy