Odwołanie do obiektu i inne zagadnienia wielowatkowe

Odwołanie do obiektu i inne zagadnienia wielowatkowe
S2
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 6 lat
  • Postów:91
0

Przy ostatnim delegacie wywala mi często błąd System.NullReferenceException - Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu. Ktoś coś zaradzi?

Kopiuj
private void button1_Click(object sender, EventArgs e)
        {

            watek1[licznik] = new Thread(wykonajWatek1);
            watek1[licznik].Start();
            licznik++; 
        }
        
        private void wykonajWatek1()
        {
            this.Invoke((MethodInvoker)delegate
            {
                kolejka[licznik] = new PictureBox();
                kolejka[licznik].Location = new Point(325, n - 150);
                kolejka[licznik].Image = wielowatkowa.Properties.Resources.car;
                kolejka[licznik].Size = new Size(20, 37);
                this.Controls.Add(kolejka[licznik]);
            });


            for (int i = 0; i < 500; i++)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    kolejka[licznik].Location = new Point(kolejka[licznik].Location.X, kolejka[licznik].Location.Y - 3);
                    this.Refresh();
                });
                Thread.Sleep(50);
            }
        } 
edytowany 2x, ostatnio: Shalom
NE
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 8 lat
  • Postów:186
0

Radzę podejrzeć wartości zmiennych, kiedy wyjątek występuje.


(konto nieaktywne)
MC
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 8 lat
  • Lokalizacja:Wrocław
  • Postów:127
0
  1. Nie uruchamiałem, ale podejrzewam, że masz race condition na zmiennej licznik,
  2. Kilka razy wciśnięty button uruchamia tyle samo wątków w Twoim kodzie, musisz zabezpieczać.
Sarrus
  • Rejestracja:prawie 14 lat
  • Ostatnio:2 dni
  • Postów:2512
0

Wyobraź sobie, że jeden wątek właśnie wykonuje pętlę for, a w tym czasie udało ci się nacisnąć przycisk. Licznik zostaje zwiększony, ale zanim wykona się linia new PictureBox drugi wątek wznawia wykonywanie pętli. Masz wówczas sytuację, że kolejka[licznik] == null. Nie musisz generalnie sobie tego wyobrażać. Możesz użyć debuggera i sprawdzić w momencie rzucenia wyjątku jaki jest stan licznika i jakie są wartości w kolejka.

Tak się jednak zastanawaiam po co ci te wątki, skoro i tak wszystkie operacje wykonujesz w wątku UI? Bardziej sensowne byłoby wykorzystanie osobnej klasy do przedstawienia samochodu. W jednym osobnym wątku iterowałbyś po obiektach (nie kontrolkach) i zmieniałbyś ich pozycje, a następnie wywoływał Refresh raz. W zdarzeniu Paint natomiast aktualizowałbyś kontrolki na podstawie tych obiektów.

edytowany 3x, ostatnio: Sarrus
S2
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 6 lat
  • Postów:91
0

Ok zabezpieczenie wątku zrobiłem.

edytowany 1x, ostatnio: spin2015
T2
  • Rejestracja:ponad 10 lat
  • Ostatnio:7 miesięcy
  • Postów:194
0

Możesz opisać co chcesz zrobić od A do Z to może lepiej będzie dało się to zrobić.

S2
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 6 lat
  • Postów:91
0

Ok z tamtymi już wiem w czym problem.

edytowany 1x, ostatnio: spin2015
T2
  • Rejestracja:ponad 10 lat
  • Ostatnio:7 miesięcy
  • Postów:194
0

Wątek się kończy gdy wykona całe zadanie :). Natomiast jak użytkownik kliknie przycisk to zawsze są tworzone wątki, stare nie są zabijane.

SO
  • Rejestracja:ponad 10 lat
  • Ostatnio:12 miesięcy
0

Picturebox się zawiesza bo wszystkie wątki korzystają z tego samego pola licznik, jak tworzysz nowy wątek to inkrementujesz ten licznik, więc rusza się tylko nowy(bo teraz na niego wskazuje licznik).

KL
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 6 lat
  • Postów:156
0

Hmmm pamiętam jak przerabiałem aplikacje z WinForma na WPF ^^ mój poprzednik coś podobnego jak ty wymyślił. W sensie dodawanie kontrolek przycisków do panelu. Dodatkowo zrobił obok 15 list przechowujących parametry przycisku. Przerobiłem to w ten sposób

Więc stworzyłem sobie model przycisku przechowujących najważniejsze parametry

Kopiuj
class ButtonCategory : Button
    {
        public int idCategory;                              // Id kategori która reperezentujemy
        public string categoryName;                         // Nazwa kategori reprezentowanej
        public int countCustomer;                           // Ilosc klientów w danej kategori przy odpowiednich parametrach kategori perezentowanej
        public int parametrKomornik;                        // Parametr komornik prezentowanej kategori   (parametr otrzymywany z API, nie jest on wykorzystywany nigdzie w aplikacji lecz stanowczo kazali nic nie ruszać oraz iż ma być on przechowywany)

        /// <summary>
        /// Tworzenie przycisku oraz przypisanie jej niezbędnych parametrów
        /// </summary>
        /// <param name="_categoryName">Nazwa</param>
        /// <param name="_countKlientow">Ilosc klientow</param>
        /// <param name="_idKategory">Id kategori</param>
        /// <param name="_parametrKomornik">parametr komornik</param>
        public ButtonCategory(string _categoryName, int _countKlientow, int _idKategory, int _parametrKomornik)
        {                                                                                            
            this.countCustomer = _countKlientow;         // przypisanie
            this.categoryName = _categoryName;           // przypisanie
            this.idCategory = _idKategory;               // przypisanie
            this.parametrKomornik = _parametrKomornik;   // przypisanie
            ConfigButton();                              // Ustawienie profilu przycisku
          
        }

        /// <summary>
        /// Funkcja zarządzająca wizualizacją przycisku
        /// </summary>
        private void ConfigButton()
        {
            
            Content = new TextBlock()                                          // Ustawienie textu na TextBlock dzieki czemu można mieć wiele linijek text w przycisku
            {
                FontSize = 11,                                                 // Ustawienie czcionki
                Text = categoryName + " ( " + countCustomer + " ) ",           // Ustawienie textu na nazwę prezentowanej kategori + "(ilość klientów)"
                TextAlignment = TextAlignment.Center,                          // Ustawienie wysrodkowania
                TextWrapping = TextWrapping.Wrap                               // Ustawienie wapingu

            }; 
            Width = 100;                                                      // Ustawienie szerokości przycisku
            Height = 50;                                                      // Ustawienie wysokości przycisku
            Margin = new Thickness(5, 5, 5, 5);                               // Ustawienie marginesu, żeby przyciski do siebie nie przylegały 
        }
    }

 

ConfigButton() - ustawia konfiguracje wyglądu przycisku.

Dodanie Przycisku do WrapPanel name="Wp_Button"

Kopiuj
 
ButtonCategory CategoryButton = new ButtonCategory("wkładamy dane jakie mamy wrzucić"); // Stworzenie obiektu oraz jego konfiguracja
WP_Button.Children.Add(CategoryButton);  // Dodanie obiketu to WarpPanelu
amountCategory_dynamic = amountCategory_dynamic + 1; // A to mam do zliczania ilości przycisków przez co klasa zarządzająca wielkością okna oraz położeniem wie jak ma powiększyć okno

CategoryButton.Click += Click_StandardCategory; // Dołożenie akcji przycisku

Fragment odwołania się do obiektu i rozpoznanie co to za obiekt z jakimi parametrami

Kopiuj
 
private void Click_StandardCategory(object sender, EventArgs e)
        {
ButtonCategory ChooseButton = (ButtonCategory)sender; // Da sprawdzenia jaka została wybrana kategoria, i teraz z obiektu ChooseButton jesteś wstanie wyciagnac informacje takie jak ustawiłeś w modelu 
}

Nie pamiętam czy w WinFormie jest WarpPanel ale jak tak to polecam. Bo on sam ustawia rozmieszczenie przycisków. Dzięki czemu jak rozciągasz okno to masz więcej przycisków w jednym rzędzie albo jak zwęzisz to masz więcej kolumn. Do tego możesz dodać suwaka i nawet przyjemnie to wygląda.

SO
Pytanie tylko co to ma wspólnego z tematem?
ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:5 dni
1
Kopiuj
        ... {
            watek1[licznik] = new Thread(wykonajWatek1);
            watek1[licznik].Start(); // 1) tu wątek startuje
            licznik++; // 2) tu zwiększasz licznik
        }
 
        private void wykonajWatek1()
        {
            this.Invoke((MethodInvoker)delegate
            {
                kolejka[licznik] = new PictureBox(); // 3) tu (BTW dlaczego całość jest w Invoke?) i poniżej odwołujesz się do kolejka[licznik]
                kolejka[licznik].Location = new Point(325, n - 150);
                kolejka[licznik].Image = wielowatkowa.Properties.Resources.car;
                kolejka[licznik].Size = new Size(20, 37);
                this.Controls.Add(kolejka[licznik]);
            });
 

Co Twoim zdaniem zagwarantuje, że cały punkt 3. wykona się PRZED 2? Masz tu typowy hazard, a ilość kodu w 3. w stosunku do ilości kodu pomiędzy 1. a 2. sugeruje, że niemal zawsze wykona się 2 (licznik++) przed 3 (kolejka[licznik]). Moim zdaniem albo nie przemyślałeś swojego pomysłu, albo kompletnie nie rozumiesz, co robisz. Zacznij od jakiegoś dużo prostszego przypadku.


SO
Moim zdaniem albo nie przemyślałeś swojego pomysłu, albo kompletnie nie rozumiesz, co robisz. stawiam na tą drugą opcję :P
ŁF
Nie zadawaj pytań związanych z tematem wątku w komentarzach. Komentarze są głównie od off-topu.
ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:5 dni
0

Gdzie umieścić licznik? Usiądź z kartką i rozrysuj sobie swój pomysł. Ja nie wiem co chcesz osiągnąć, a Ty tego nie podałeś. Widzę jakąś tablicową zmienną kolejka, kolejną watek1 ("1" do tablicy? WTF? A masz też watek2? Co taka nazwa powie Ci za pół roku?). Napisz co dokładnie chcesz uzyskać i jak się do tego zabrałeś, to coś pomyślimy.


Sarrus
ja się domyślam co robi i napisałem, że źle to robi, ale tą część mojego postu olał
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)