Wątek, a GUI

0

Witam

Od razu zaznaczam, że problem nie jest związany z Invoke, ani nawet z kontrolkami, lecz z wieszaniem całego GUI. ;-P Więc po kolei... Uważam, że najłatwiej będzie zrozumieć mój problem na kawałkach kodu:

class Class1
    {
        private void func()
        {
            Class2 class2Instance = new Class2();
            string ToCoZwrocilWatek = class2Instance.funcWithThread();
        }
    }
class Class2
    {
        string WynikWatku;
        public string funcWithThread()
        {
            Thread trd = new Thread(new ThreadStart(ThreadTask));
            trd.IsBackground = true;
            trd.Start();
            return WynikWatku;
        }

        private void ThreadTask()
        {
            //tu wykonują się jakieś czasochłonne operacje
            //np. łączenie z internetem itp.
            WynikWatku=JegoWynik;
        }
    }

Gdy kod z wątku jest w funkcji wiesza mi się cały program :/ . Pierwszym rozwiązaniem jakie wpadło mi do głowy były wątki. Tylko nie bardzo wiem jak zrobić, żeby w zmiennej ToCoZwrocilWatek było faktycznie to co on mi przetworzył (np. źródło stronki). Słusznym wyjściem z tego problemu są chyba eventy, lecz czy wtedy kod mi się nie za bardzo pokomplikuje?
Myślałem też nad tym, czy da się zrobić to w drugą stronę, wszystko dzieje się w wątku głównym, a samo GUI rysowane jest w innym wątku, ale jakoś nie bardzo mogę sobie to wyobrazić...
Proszę was o pomoc, jak to zrobić?
Wątki od zawsze były dla mnie czarną magią (semafory, itp.? co to w ogóle jest?) :| .

Pozdrawiam, Wronq [!!!]

PS. jak zrobić, żeby w code kolorowało składnię C#?
PS2. Zmieniłem trochę kod, żeby było bardziej zrozumiale.

0

W ogóle nie mam pojęcia co to jest wynikWątku który niby zwracasz w tej funkcji funcWithThread (nie ma go nigdzie zadeklarowaneg), swoją drogą zwracasz go od razu po włączeniu wątku, mógłbyś użyć funkcji .Join() na wątku uruchamianym, żeby poczekać, aż skończy pracę, bo tego wyniku może w ogóle jeszcze nie być.

pzdr

0

Myślałem, że to oczywiste, że to będzie jakiś string, który jest wynikiem (pojawia się gdzieś w wątku i dla mnie jest wynikiem jego pracy) wątku, więc nigdzie nie deklarowałem zmiennej... Join() próbowałem, lecz, czy to nie wychodzi na to samo, co w przypadku, gdy tego wątku w ogóle nie ma? Program, i tak, i tak się wiesza.
Właśnie o to mi chodzi... Ja go zwracam, a jego nie ma. Więc jak mogę poczekać do momentu zakończenia wątku, nie wieszając programu?

0
Wronq napisał(a)

Więc jak mogę poczekać do momentu zakończenia wątku, nie wieszając programu

Użycie Join powoduje że wątek główny zaczeka, aż zakończy się wątek poboczny... rysowania kontrolek itp nie da się przenieść do innego wątku.

Proponuje użyć właśnie eventu, który by został wywołany, gdy zakończy się wątek poboczny. Jeżeli dobrze to zaplanujesz, wcale nie skomplikujesz sobie, aż tak bardzo kodu.

0

tak na prawde chcesz uzyc wywolania asynchronicznego z callback'iem
najlatwiej uzyc delegatow

0

Poczytałem troszkę o tych callback'ach. Czy to nie wychodzi wtedy na to samo, jakbym na koniec pracy wątku posłużył się eventem?

0

tak, ale po co robic cos, co srodowisko moze zrobic za ciebie
poza tym mniej kodu
do funkcji startowej watku w paskudny sposob przekazuje sie parametry, a tu masz eleganco zdefiniowany delegat, wiec mniejsza szansa pomylki niz przy toworzeniu np. jakiejs tablicy object

0

Dzięki za podpowiedź. Myślałem, że będzie jakiś jeszcze bardziej prosty sposób, ale i tym nie pogardzę.

0

Wrong, a myślałeś na background workerem?

Pozdrawiam

0

Nawet mi to przez myśl nie przeszło.
Nie mam z nim większego doświadczenia. Użyłem go tylko raz w mojej krótkiej znajomości z C# i za nic nie rozumiem, ani jego idei, ani sposobu jego działania.

0

jak to? idea jest przeciez prosta, masz dlugo trwajaca prace do wykonania, nie mozesz glokowac gui (bo sie zwiesi), wiec kierujesz prace na boczny tor (nie obchodzi cie zaden watek, jego startowanie etc. to robi za ciebie klasa)
kluczem sa 3 event'y (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker_events(v=VS.100).aspx)

  1. wykonujesz prace - DoWork
  2. informuj o wykonaniu jakiejs czesci pracy (zeby gui moglo np. przesunac jakis pasek postepu) - ProgressChanged
  3. prace skonczona, mozesz odegrac fanfary - RunWorkerCompleted
0

No dobra. 2 i 3 są oczywiste ale 1. nie bardzo. Wątek jest prosty jak cep. Coś, w środku pętla, lub coś co się długo wykonuje. w BW nie, event, który nie bardzo wiem, kiedy się rzuca i nie bardzo wiem, co mam robić, jak już go dostanę.

0

jak go dostaniesz to zaczynasz swoje obliczenia i nie ty go rzucasz tylko BW jak zostanie wystartowany, wiec odsluga tego eventu to praca, ktora chcesz wykonac

1 użytkowników online, w tym zalogowanych: 0, gości: 1