Jaką pętle zastosować?

0

Chciałbym, aby dany blok instrukcji nie był wykonany, aż do spełnienia 2 warunków jednocześnie.
Jaką pętle zastosować, tak żeby się powtarzała i sprawdzała warunki? Nie wiem kiedy zostaną spełnione warunki.

0

while(a > 0 && b > 0)

2

albo mozna to zrobic troszke inaczej, jezeli te warunki sa polaczone ze soba jakas logika (biznesowa, albo po prostu w kodzie jeden mocno zalezy od drugiego) to wtedy mozna polaczyc to w klase i sprawdzac

while(nameOfValidator.IsValid()){}

gdzies w petli wywolujesz Validate() przez co moga zostac zmienione te parametry na ktorych Ci zalezy

Dlaczego tak zrobic?

Bo mozesz latwo wyciagnac zaleznosc i latwiej takie cos testowac

0

Mozesz uzyc kazdej petli (nawet for, bo tam tez jest warunek logiczny), ale najbardziej sensowny wydaje sie wybor sporod: while lub do-while. Jezeli nie wiesz kiedy warunki zostana spelnione musisz jednak wziac pod uwage jak uniknac dzialania petli w nieskonczonosc.

0

Problem polega na tym, że chce przyjąć byte z serial portu. Program za szybko się wykonuje. Wiec pomyślałem sobie, że warto by było zrobić pętle, która się wykonuje i jak przyjdą dane SerialPort.IsOpen > 0 i wartość tego byte co przyjdzie będzie równa 0. Wykona się kod. Problem polega na tym, że jak zrobię przeciwieństwo czyli (SerialPort.IsOpen !=0 i wartość byte != 1) program nie reaguje. Reasumując chce, żeby pętla przechodziła tyle razy aż przyjdą dane na serial port i te dane będą równe 1 wykona się blok instrukcji.

0

@bartk: Nie ma tam żadnej pętli, jak coś się łączy na porcie szeregowym to wyzwala przerwanie sprzętowe, które uaktywania eventy.

0

ale zeby byl wysluchany event to musisz miec petle ktora nasluchuje i sprawdza co jakis czas czy cos przyszlo. Wiec wewnetrznie jestem prawie pewien (bo nie widzialem kodu wiec nie jestem 100% pewny) jest petla ktora wyczekuje na eventy

0

No dobra w takim razie jak mam już taki MyDataReceivedHandler jak w poście fasadina, to jak mam się odwołać w głównym programie do tego? Czyli powiedzmy, że chce jeżeli przyjdzie byte o zmiennej 1, wykona się blok instrukcji ?

0

Pytanie trochę z innej strony, komunikujesz się za pomocą ASCII, czy binarnie? SerialDataReceivedEventHandler nie koniecznie dobrze sobie radzi z komunikacją binarną, potrafi wyskoczyć po 1 bajcie, albo po kilku.

0

Czy otwierasz w ogóle port:

sp = new SerialPort("COM3");
                sp.Open();
                sp.DataReceived += Sp_DataReceived;

otwarcie portu nie jest asynchroniczne, czeka aż się otworzy nie ma potrzeby za bardzo sprwdzać isOpen.

0

Może inaczej. W Klasie KlasaObslugiUSB mam umieszczonego SerialDataReceivedEventHandler. Teraz chce stworzyć metodę w programie głównym, w której jeżeli program odbierze byte, to sprawdzi jaka jest jego wartość i wykona odpowiedni blok instrukcji. Największym problem jest to, że Program za szybko działa i po odebraniu wyskakuje błąd "System.NullReferenceException: 'Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.'" Chodzi o to, że program dalej sie wykonuje, zamiast wykonywać się po sprawdzeniu warunków. Czyli w tym przypadku Odebrania bytes i sprawdzenia jego wartości.

public partial class MainWindow : Window
{



    public MainWindow()
    {
        InitializeComponent();
        KlasaObslugiUSB.Instancja.Open();

    }

    private void Start_Click(object sender, RoutedEventArgs e)
    {

        KlasaObslugiUSB.Instancja.StartGry(); //wysłanie sygnału StartGry
        //Thread.Sleep(250);
        ZapalLampki();


    }

    private void ZapalLampki()
    {
        
        while (KlasaObslugiUSB.Instancja.Wynik[0] != 1)
        {
            Ellipse01.Fill = Brushes.Blue;
            Ellipse02.Fill = Brushes.Blue;
            Ellipse03.Fill = Brushes.Blue;
            Ellipse04.Fill = Brushes.Blue;
            Ellipse05.Fill = Brushes.Blue;
            Ellipse06.Fill = Brushes.Blue;
            Ellipse07.Fill = Brushes.Blue;
            Ellipse08.Fill = Brushes.Blue;
            Ellipse09.Fill = Brushes.Blue;
            Ellipse10.Fill = Brushes.Blue;
        }
        
    }
    
        
    

    private void Zeruj_Click(object sender, RoutedEventArgs e)
    {
        Ellipse01.Fill = Brushes.Blue;
        Ellipse02.Fill = Brushes.Blue;
        Ellipse03.Fill = Brushes.Blue;
        Ellipse04.Fill = Brushes.Blue;
        Ellipse05.Fill = Brushes.Blue;
        Ellipse06.Fill = Brushes.Blue;
        Ellipse07.Fill = Brushes.Blue;
        Ellipse08.Fill = Brushes.Blue;
        Ellipse09.Fill = Brushes.Blue;
        Ellipse10.Fill = Brushes.Blue;
    }
}
1

Idąc tym tokiem działania, (kod ogólnie nie powinien tak wyglądać, trzeba by dużo pozmieniać, no ale idąc tym tokiem)
zamiast

while (KlasaObslugiUSB.Instancja.Wynik[0] != 1)

daj

while (KlasaObslugiUSB.Instancja.IsValid())

a w klasie KlasaObslugiUSB dodaj metodę
IsValid() {
return = (wynik!=null&&wynik.length>0);
}
I dodaj

private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //tu przypisywanie wartości do wynik
        }

i

sp.DataReceived += Sp_DataReceived; //zaraz po sp.Open();

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