2009-06-02 13 views

Odpowiedz

0

W zależności od modelu, chcesz, aby twój wątek roboczy oddzwonił do swojego twórcy (lub do innego procesu) po zakończeniu pracy lub musisz odpytywać wątek roboczy co jakiś czas, aby sprawdzić, czy jest zrobione, a jeśli tak, to uzyskaj wynik.

Idea oczekiwania na wątek roboczy, aby zwrócić jego wynik, podważa korzyści wynikające z wielowątkowości.

1

uruchamia proces asynchronicznie i powraca i kontynuuje wykonywanie kodu przed zakończeniem procesu. Jeśli chcesz uzyskać wynik BackgroundWorker, musisz utworzyć zmienną instancji, aby zatrzymać tę wartość i sprawdzić ją po ukończeniu BackgroundWorker.

Jeśli chcesz poczekać do zakończenia pracy, nie potrzebujesz BackgroundWorker.

+1

Istnieje różnica między oczekiwania i _locking górę UI_ robiąc tak. –

+0

@TSar: To prawda, chociaż w kontekście pracy ze starszym komponentem, takim jak 'BackgroundWorker', semantyka" czekania "jest względnie złożona (przynajmniej w celu zademonstrowania, jak to" czeka "). Coś takiego jest znacznie łatwiejsze do wyrażenia dzięki składni 'async' i' await' teraz i pozwoliłoby deweloperowi pozbyć się większości przypadków użycia dla 'BackgroundWorker' w ogóle. –

+0

Byłoby miło uzupełnić twoją odpowiedź alternatywnymi, zamiast po prostu powiedzieć OP, aby nie używał BackgroundWorker. Jak się teraz czyta, wygląda na to, że sugerujesz, aby w ogóle nie używać żadnego rodzaju wielowątkowości - a to zamknęłoby aplikację, dopóki proces się nie zakończy. –

1

Można mieć swój wątek podnieść zdarzenie z obiektu jako argument:

ThreadFinishedEvent(this, new ThreadEventArgs(object)); 

gdzie:

public class ThreadEventArgs : EventArgs 
{ 
    public ThreadEventArgs(object object) 
    { 
     Object = object 
    } 

    public object Object 
    { 
     get; private set; 
    } 
} 
18

jestem przy założeniu, że nie chcą blokować i czekać na RunWorkerAsync() dla wyników (jeśli tak, to nie ma powodu, aby uruchamiać asynchroniczne!

Jeśli chcesz otrzymywać powiadomienia o zakończeniu procesu w tle, przyłącz się do zdarzenia RunWorkerCompleted. chcesz przywrócić jakiś stan, zwróć go w elemencie Result zdarzenia Argumenty zdarzenia.

EDIT: I pisał przedwcześnie - zakończył mój przykładowy kod

Przykład:

 


    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     // do your thing 
     .... 
     // return results 
     e.Result = theResultObject; 
    } 

    // now get your results 
    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     MyResultObject result = (MyResultObject)e.Result; 
     // process your result... 
    } 

 
87

W swojej obsługi DoWork zdarzeń dla BackgroundWorker (czyli tam, gdzie praca odbywa się w tle) jest argument DoWorkEventArgs. Ten obiekt ma publiczny obiekt właściwości Wynik. Kiedy twój pracownik wygeneruje swój wynik (w twoim przypadku, List<FileInfo>), ustaw e.Result na to i zwróć.

Po ukończeniu zadania przez BackgroundWorker wyzwala ono zdarzenie RunWorkerCompleted, które jako argument ma obiekt RunWorkerCompletedEventArgs. RunWorkerCompletedEventArgs.Result będzie zawierać wynik z Twojego BackgroundWorker.

przykład:

private void bgw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    int result = 2+2; 
    e.Result = result; 
} 

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    int result = (int)e.Result; 
    MessageBox.Show("Result received: " + result.ToString()); 
} 
+0

Bahhh dziękuję! – ganjeii

0

Ogólnie rzecz biorąc, gdy uruchomiony jest asynchronicznie procesu gwint pracownik powinien wywołać przekazać lub zwolnić zdarzenia (jak ChrisF).

Możesz sprawdzić nowy PFX, który ma funkcję współbieżności, która może zwracać wartości.

Na przykład istnieje funkcja o nazwie Parallel.ForEach(), która ma przeciążenie, które może zwrócić wartość.

sprawdzić to uwagę, aby uzyskać więcej informacji

http://msdn.microsoft.com/en-us/magazine/cc817396.aspx

Powiązane problemy