2011-06-30 16 views
6

Możliwe duplikaty:
Must every BeginInvoke be followed by an EndInvoke?
Is EndInvoke() optional, sort-of optional, or definitely not optional?Asynchroniczne wywoływanie - czy wymagane jest EndInvoke?

Mam wielowątkowych aplikacji, a jeden z wątków wtórnych musi dostać jakiś kod do wykonania w głównym wątku raz kilka minut. Nie ma żadnej wartości zwracanej, a drugi wątek nie dba o to, czy podnosi wyjątki, czy też nie działa.

Do tej pory otrzymywałem go do uruchomienia kodu przez Form.Invoke, ale czasami zajmuje to znacznie więcej czasu niż zwykle (kilka sekund) i blokuje wątek, dopóki nie zostanie ukończony. Potrzebuję drugiego wątku, aby móc kontynuować wykonywanie bez przeciągania przez kilka sekund.

Brzmi, jakby to dobrze działało, ale tak naprawdę nie mam gdzie zadzwonić pod numer EndInvoke, ponieważ nie chcę na niego czekać ani uzyskać wartości zwracanej. Biorąc pod uwagę, że wywoływany kod wiąże się z wieloma wywołaniami natywnymi, nie jestem pewien, czy jest to dobry pomysł, aby nie EndInvoke.

Czy muszę w ogóle zadzwonić pod numer EndInvoke, czy jest jakiś inny sposób uzyskania kodu do uruchomienia w głównym wątku formularza, który powinienem użyć zamiast tego?

Dzięki =)

Odpowiedz

6

Możesz zadzwonić do EndInvoke, aby pobrać zwrotną wartość od delegata, , jeśli jest to konieczne, ale nie jest to wymagane. EndInvoke będzie blokował, dopóki nie zostanie przywrócona wartość zwracana.

Źródło: http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx pod Uwagi

+0

Awesome, więc mogę zmienić moje 'Invoke's na' BeginInvoke's bez wysadzania czegokolwiek. –

3

Należy upewnić się, że EndInvoke nazywa, ale można to zrobić bardzo łatwo, coś takiego:

var action = new Action(SomeMethodGroup); 

    action.BeginInvoke(new AsyncCallback(

     x => (x.AsyncState as Action).EndInvoke(x)), action); 
+0

wierzę OP mówi o Form.BeginInvoke w szczególności a nie kroki/EndInvoke wzór w ogóle. Patrząc na MSDN, Form.BeginInvoke nie wydaje się dokładnie przestrzegać wzoru Begin/EndInvoke. – dtb

+0

@dtb, W rzeczywistości, nie wierzę, że jest to bezwzględnie konieczne dla Form.BeginInvoke lub Delegate.BeginInvoke, ponieważ moim zdaniem tworzy on tylko WaitHandle, jeśli spróbujesz czekać (np. Wywołanie EndInvoke.) The WaitHandle musi być oczyszczony w górę, ale będzie tak, jeśli zadzwonisz do EndInvoke. –

+0

Dobra sprawa, może nie potrzebujesz EndInvoke, może prostej metody, która może działać jako strategia "strzelaj i zapomnij"? –

4

Typowym sposobem wywołania EndInvoke jest tym zwrotnego zakończenia z BeginInvoke, aby można było wywołać EndInvoke w wywołaniu zwrotnym. Jest to ważniejsze dla metod Begin/End, które robią coś bardziej specyficznego niż Invoke, na przykład BeginRead/EndRead; w tych ostatnich przypadkach Koniec może być wymagany do czyszczenia, a także zazwyczaj (ponownie) wyrzucać wszelkie wyjątki, które wystąpiły w trakcie procesu.