Wywołanie zdarzenia/metody po zakończeniu Task'u

Wywołanie zdarzenia/metody po zakończeniu Task'u
Astrocyt
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Witam
Otóż podczas pisania programiku w WinForms natrafiłem na taki projektowy problem ( nie wklejam całego tylko taki skrót )

Kopiuj
private Object jakisObjekt=new object();

	void WykonajOperację
	{
		Task t = new Task(()=>
		{
				this.jakisObjekt = objektKlasy.długotrwałaMetoda();
				
		});
			t.Start();
	}
	void ToMaSięWykonaćPoTasku()
	{
		//Kod zmieniający Enable pewnych kontrolek, 
                //tutaj jest niezbędny jakiśObjekt
	} 

WykonajOperację odpala się wtedy, gdy button zostanie kliknięty. Na tasku jest odpalana pewna metoda która wymaga trochę czasu ( nie chcę zawieszać GUI ). I tutaj mam pytanie. Jak odpalić na wątku głownym ( wątku GUI ) metodę ToMaSięWykonaćPoTasku ? Chciałbym jak najbardziej uniknąć this.Invoke(). Czy jest możliwe zarejestrowanie jakiegoś zdarzenia po zakończeniu tasku który zostanie odpalony w wątku głównym ( próbowałem stworzyć private event i wywoływać na końcu task'u ale i tak wywalało błąd dotyczący operacji międzywątkowych)
Proszę o pomoc
Pozdrawiam
Astrocyt

fourfour
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 627
FA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 475
Sarrus
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2512
0

A czemu ma się funkcja wykonać w wątku głównym? Jeżeli chodzi o manipulację GUI to użyj InvokeRequired oraz Invoke

  • Rejestracja: dni
  • Ostatnio: dni
2

w .NET 4.5 wyglądałoby to po prostu tak:

Kopiuj
    void async WykonajOperację
    {
        this.jakisObjekt = await Task.Run(objektKlasy.długotrwałaMetoda);
        ToMaSięWykonaćPoTasku();
    }

w .NET 4.0

Kopiuj
Task.Factory.StartNew(objektKlasy.długotrwałaMetoda).ContinueWith(ToMaSięWykonaćPoTasku, TaskScheduler.FromCurrentSynchronizationContext());

czemu chcesz "uniknąć Invoke" - do tego ono służy i gdzieś wewnętrznie i tak zostanie wywołane

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
3

czy długotrwałaMetoda jest długotrwała bo na coś oczekuje (pakiet sieciowy..) czy jest długotrwała pod względem obliczeniowym?
to bardzo istotna różnica.

poza tym wygodniej jest użyć async/await.

Kopiuj
async Task WykonajOperację
{
    this.jakisObjekt = await Task.Run(objektKlasy.długotrwałaMetoda);
    ToMaSięWykonaćPoTasku();
}

EDIT: ktoś mnie ubiegł ;-)

Astrocyt
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Chyba jednak to zrobie przez Invoke - będzie najprościej. W każdym razie dzięki za pomoc, cenna wiedza na przyszłość.
Pozdrawiam
Astrocyt

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.