Skocz do zawartości
Zamknięcie Forum PC LAB

Szanowny Użytkowniku,

Informujemy, że za 30 dni tj. 30 listopada 2024 r. serwis internetowy Forum PC LAB zostanie zamknięty.

Administrator Serwisu Forum PC LAB - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie: wypowiada całość usług Serwisu Forum PC LAB z zachowaniem miesięcznego okresu wypowiedzenia.

Administrator Serwisu Forum PC LAB informuje, że:

  1. Z dniem 29 listopada 2024 r. zakończy się świadczenie wszystkich usług Serwisu Forum PC LAB. Ważną przyczyną uzasadniającą wypowiedzenie jest zamknięcie Serwisu Forum PC LAB
  2. Dotychczas zamowione przez Użytkownika usługi Serwisu Forum PC LAB będą świadczone w okresie wypowiedzenia tj. do dnia 29 listopada 2024 r.
  3. Po ogłoszeniu zamknięcia Serwisu Forum od dnia 30 października 2024 r. zakładanie nowych kont w serwisie Forum PC LAB nie będzie możliwe
  4. Wraz z zamknięciem Serwisu Forum PC LAB, tj. dnia 29 listopada 2024 r. nie będzie już dostępny katalog treści Forum PC LAB. Do tego czasu Użytkownicy Forum PC LAB mają dostęp do swoich treści w zakładce "Profil", gdzie mają możliwość ich skopiowania lub archiwizowania w formie screenshotów.
  5. Administrator danych osobowych Użytkowników - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie zapewnia realizację praw podmiotów danych osobowych przez cały okres świadczenia usług Serwisu Forum PC LAB. Szczegółowe informacje znajdziesz w Polityce Prywatności

Administrator informuje, iż wraz z zamknięciem Serwisu Forum PC LAB, dane osobowe Użytkowników Serwisu Forum PC LAB zostaną trwale usunięte ze względu na brak podstawy ich dalszego przetwarzania. Proces trwałego usuwania danych z kopii zapasowych może przekroczyć termin zamknięcia Forum PC LAB o kilka miesięcy. Wyjątek może stanowić przetwarzanie danych użytkownika do czasu zakończenia toczących się postepowań.

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

Zdziwiony

[C#]Wątki

Rekomendowane odpowiedzi

Witam. Oto mój kod:

MyProgressBar.IsIndeterminate = true;
if(CheckBox.IsChecked == true)
           {
               Thread thr = new Thread(funkcja);
               thr.Start();           
           }
if(CheckBox2.IsChecked == true)
           {
               Thread thr = new Thread(funkcjanr2);
               thr.Start();           
           }
//wątek dalej się wykonuje....
thr.Join(); // jeżeli tego użyje zawiesi się całe okno
MyProgressBar.IsIndeterminate = false;

 

Jak widać wyżej za pomocą tego kodu chce wykonać jakieś czynności w osobnych wątkach, jednak przed tym "uruchamiam" sobie progressbara, a po wykonaniu tych wątków chcę go zatrzymać. Niestety nie mogę tego zrobić ponieważ progressbar zatrzyma się chwile po wywołaniu jakiegoś wątku...(Wszystko przez to, że główny wątek nadal będzie sobie działał). Natomiast jeżeli użyje metody thr.Join(); to całe okno zawiesi się i progressbar w ogóle nie zadziała. Ma ktoś jakiś pomysł na to jak rozwiązać ten problem ?

 

Proszę o pomoc.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

na końcu wątku daj sobie:

 

           this.Invoke((MethodInvoker)delegate
           {
               MyProgressBar.IsIndeterminate = false;
           });

 

zakładam ze this dziedziczy po Control.

 

Ale tak w zasadzie żeby to wygladało poprawnie to;

Nazywaj obiekty i zmienne normalnie, a nie CheckBox1 Checkbox2 itp...

Ponieważ oba warunki mogą być jednocześnie spełnione, to mogą sie odpalić oba wątki naraz. Wtedy przed zakończeniem danego wątka musisz sprawdzić czy trzeba zatrzymać pbara, czy jezscze czekamy na drugi wątek.

 

Zrób sobie zmienną int threadsCount = 2;

a potem funkcję

private void stopProgressBarIfNecessary()
{
  threadsCount--;
  if(threadsCount==0)
  {
      this.Invoke((MethodInvoker)delegate
      {
          MyProgressBar.IsIndeterminate = false;
      });
  }
}

 

PS. Z Pbara zakładam ze piszesz to w WPF, a "this.Invoke" jest dla WinFormsów, wiec poszukaj w google jak sie dobrać do GUI z wątka w WPFie.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

mówię z góry, że nie znam c# ale rozsądek podpowiada, że po wyjściu ze scope {} thr ginie i join potem jest robiony na zniszczonym obiekcie

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

BlackBishop

 

tak, metoda z thr.Join jest w ogóle niekompilowalna, bo wyszedł poza scope thr... ale to nie jest podstawą problemu :P

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

na końcu wątku daj sobie:

 

           this.Invoke((MethodInvoker)delegate
           {
               MyProgressBar.IsIndeterminate = false;
           });

 

zakładam ze this dziedziczy po Control.

 

Ale tak w zasadzie żeby to wygladało poprawnie to;

Nazywaj obiekty i zmienne normalnie, a nie CheckBox1 Checkbox2 itp...

Ponieważ oba warunki mogą być jednocześnie spełnione, to mogą sie odpalić oba wątki naraz. Wtedy przed zakończeniem danego wątka musisz sprawdzić czy trzeba zatrzymać pbara, czy jezscze czekamy na drugi wątek.

 

Zrób sobie zmienną int threadsCount = 2;

a potem funkcję

private void stopProgressBarIfNecessary()
{
  threadsCount--;
  if(threadsCount==0)
  {
      this.Invoke((MethodInvoker)delegate
      {
          MyProgressBar.IsIndeterminate = false;
      });
  }
}

 

PS. Z Pbara zakładam ze piszesz to w WPF, a "this.Invoke" jest dla WinFormsów, wiec poszukaj w google jak sie dobrać do GUI z wątka w WPFie.

Tak pisze w wpf, i mam coś takiego:

            #region obsluga GUI
           Dispatcher.Invoke(new Action(delegate { TabCore.IsEnabled = false; }));
           //progressbar
           Dispatcher.Invoke(new Action(delegate { MyProgressBar.IsIndeterminate = true; }));
           #endregion

Jedyną rzeczą jaką mi teraz do szczęścia potrzeba to sprawdzenie czy trzeba zatrzymać progressbara, czy też nie.

Ale nie za bardzo rozumiem tutaj twoją metodę tego sprawdzania ;/ (W swoim programie mam większą ilość checkboxów, a i mam w planach dodać ich jeszcze więcej i wydaje mi się, że w takim przypadku ta metoda zawiedzie)

BlackBishop

 

tak, metoda z thr.Join jest w ogóle niekompilowalna, bo wyszedł poza scope thr... ale to nie jest podstawą problemu :P

Rzeczywiście :lol2: , pisałem z pamięci i nie zauważyłem ;p

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

MyProgressBar.IsIndeterminate = true;
await twojaFunkcja();
MyProgressBar.IsIndeterminate = false;

Poczytaj o async await w .NET 4.5.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

mówię z góry, że nie znam c# ale rozsądek podpowiada, że po wyjściu ze scope {} thr ginie i join potem jest robiony na zniszczonym obiekcie

Czystonz ciekawości pytam: masz na myśli zmienne automatyczne?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeśli masz większą ilość chekboxów, to zorganizuj je w kolekcje, tak samo jak wątki, moze opakuj je w obiekty, rejestruj które wątki się zakończyły i usuwaj je z kolekcji, jak ona będzie pusta, to zatrzymuj pbara.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

MyProgressBar.IsIndeterminate = true;
await twojaFunkcja();
MyProgressBar.IsIndeterminate = false;

Poczytaj o async await w .NET 4.5.

Dzięki! :D

Ta funkcja jest dużo prostsza od bawienia się w wątki :P

 

Zmodyfikowany kod:

        private async void Start_Click(object sender, RoutedEventArgs e)
       {        
           //zablokowanie GUI i włączenie progressbara
           TabCore.IsEnabled = false;
           MyProgressBar.IsIndeterminate = true;
           if (CheckFunkcja.IsChecked == true)
           {
               //czekaj na wykonanie wątku
               await Task.Run(() => Funkcja()); 
           }
           //włączenie GUI i wyłączenie progressbara
           TabCore.IsEnabled = true;
           MyProgressBar.IsIndeterminate = false;
       }

 

Mam tylko wątpliwości, czy powinienem dopisywać tutaj

private [b]async[/b] void

, czy może powinienem stworzyć osobną funkcję, i po kliknięciu przycisku ją wywoływać ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeżeli usuniesz "async" z podanego kodu, to przecież program się nie skompiluje. Tylko metody/funkcje typu "async" mogą używać wewnątrz await. Pamiętaj o jednej istotnej rzeczy, jeżeli tworzysz swoją metodę asynchroniczną, która w środku korzysta ze słowa "await", to nigdy nie zwracaj void. Przykładowo:

 

Źle

private async void MojaMetoda()

Dobrze

private async Task MojaMetoda()

Więcej tutaj http://msdn.microsoft.com/en-us/magazine/jj991977.aspx. Tutaj może pojawić się pytanie - czy w takim razie powinienem dodać Task do obsługi zdarzenia Start_Click? Z jednej strony tak, ale z drugiej nie jest to możliwe (program się nie skompiluje). WPF i WindowsForms zostały napisane dużo wcześniej i nie są w pełni zgodne z obecnymi standardami. To jeden z wyjątków gdy stosuje się "async void".

 

Jeżeli chcesz wew. swojej metody tylko odpalić Task'a i go zwrócić to wystarczy (bez async):

private Task MojaMetoda()

Natomiast w obsłudze kliknięcia piszesz:

await twojaFunkcja();

Możesz też odpalić kilka Task-ów na raz i poczekać na wszystkie.

await Task.WhenAll(task1, task2);

Jeżeli bardziej jesteś zainteresowany programowaniem desktopowym (WPF itp.) to jak będziesz miał czas to poczytaj o Reactive Extensions (jak już zapoznasz się z Taskami oraz async await).

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...