Kończenie działania wątku - problem

0

Witam.
Od dłuższego czasu pisze sobie program na palmtopa wykorzystującą komunikację bluetooth do odbioru i wysyłania danych. Program jako tako działa ale został mi jeszcze jeden problem do rozwiązania. Odbiór i wysyłanie danych robię w wątku który tworze w momencie kliknięcia buttona "Start":

      private void btnStart_Click(object sender, EventArgs e)
        {
            lock (this)
            {

                if (startThreadRunning)
                    return;
                else
                    startThreadRunning = true;
            }

            impulses = "ERRTST_1," + txtImpulses.Text + "," + Convert.ToString(Convert.ToDouble(txtImpulses.Text) * 2);
            constCounter = Convert.ToDouble(txtMeter.Text);
            power = (Convert.ToDouble(lblU1.Text) * Convert.ToDouble(lblI1.Text) 
            double frequency = (((power * (Convert.ToDouble(txtMeter.Text) / 1000)) / 3600));
            double time = 1 / frequency;

            __write(impulses, 220);          // Thread.Sleep(220);
            th = new Thread(new ThreadStart(readimpuls));
            th.IsBackground = true;
            th.Start();
            btnStart.Enabled = false;
            btnStop.Enabled = true;
       
        }

Funkcja readimpuls() wygląda tak:

       private void readimpuls()
        {

            
            string[] arr = null;
            //Cursor.Current = Cursors.WaitCursor;

            while (!disconnected)
            {
                try
                {

                    string s = __write("RDERR_", 150);              // Thread.Sleep(150);
                    arr = s.Split(' ');

                    if (arr.Length != 4 || (arr.Length == 4 && arr[3].Equals("-1")))
                    {
                        //Cursor.Current = Cursors.Default;
                        lock (this)
                        {
                            startThreadRunning = false;
                            th = null;
                        }
                        MessageBox.Show("Blad");
                        btnStart.Enabled = true;
                        btnStop.Enabled = false;
                        return;
                    }

                    if (arr.Length == 4 && arr[3].Equals("1"))
                        break;
                }
                catch
                {
                }
            }

            if (arr.Length != 4) // ERROR, ACHTUNG, BLAD!!! :-X
                return;
            try
            {
                double energyWZ = ((power * Convert.ToDouble(arr[1])) / 3600);
                double failt = ((((Convert.ToDouble(arr[0]) / (constCounter / 1000)) - ((constCounter / 1000) * energyWZ)) / ((constCounter / 1000) * energyWZ)) * 100);
                //return failt;
                string invoke = Convert.ToString(failt);
                btnStart.Enabled = true;
                btnStop.Enabled = false;
                lblFailt.Invoke(new updateText(UpdateText), invoke);
                lock (this)
                {
                    startThreadRunning = false;
                    th = null;
                }
                return;
            }
            catch { }

        }

ten wątek działa do momentu aż dostanę taką odpowiedź jaką chcę. Chciałem jednak trochę to rozszerzyć i móc przerywać działanie wątku. Do tego celu stworzyłem sobie buttona "Stop":

       private void btnStop_Click(object sender, EventArgs e)
        {
            if (th != null)
            {
                try
                {
                    th.Abort();
                    btnStop.Enabled = false;
                    btnStart.Enabled = true;
                    th = null;
                    startThreadRunning = false;
                }
                finally
                {
                    lock (this)
                    {
                        th = null;
                        startThreadRunning = false;
                    }
                }
                
            }
            
            impulses = "ERRTST_0,0,0";
            __write(impulses, 150);          // Thread.Sleep(150);
        }

I tu jest problem, ponieważ niby mi przerywa działanie wątku, ale za to całkowicie zawiesza cały program.
Czy ktoś może mi jest w stanie wyjaśnić dlaczego tak się dzieje i ewentualnie pomóc rozwiązać problem. Za wszelką pomoc z góry dziękuję.

Pozdrawiam.

1

Abort to beznadziejna metoda zabijania wątków.
To try{ ... } catch { } też nie jest ciekawe... :/
T to:

try
{
th.Abort();
btnStop.Enabled = false;
btnStart.Enabled = true;

                <b>th = null;</b>
                <b>startThreadRunning = false;</b>
            }
            finally
            {
                lock (this)
                {
                    <b>th = null;</b>
                    <b>startThreadRunning = false;</b>
                }
            }

jakiś STUB czy pomyłka?

Próbowałeś debugować? Powiedz dokładnie na której instrukcji się wywala (wiem że debugowanie z wątkami jest a bit trudniejsze, ale się da.

////////////////////////////////////////////////////////

@co do ostatniego postu:
0_0 [lol]

jeśli natrafię na problem nie do rozwiązania dla mnie to się na pewno odezwę

Dzięki... łaskawco ;)

0

Lepiej cos takiego jednak:

while (!disconnected && !stopThread)
...

//a przerywasz:
thread.stopThread = true;
0

Przepraszam, ale się trochę zbyt pośpieszyłem z wystawieniem mojego problemu na forum. Program jednak się nie zawieszał, tylko czekał aż do odebrania pewnej sekwencji danych (funkcja __write()). Za wszelkie uwagi i pomoc dziękuję. Spróbuję poprawić ten wątek i jeśli natrafię na problem nie do rozwiązania dla mnie to się na pewno odezwę :-)
Pozdrawiam

0

Witam ponownie.
Znów mam mały problem dotyczący wątków dlatego pozwoliłem sobie nie zakładać nowego tematu tylko podpiąć pod stary.
A mianowicie chciałbym aby w funkcji readimpuls(), która jest powyżej, po otrzymaniu i wyświetleniu danych które chcę, buttony start oraz stop zmieniały swoją właściwość Enabled.
Chodzi i o coś takiego:

btnStart.Enabled = true;
            btnStop.Enabled = false;

Próbowałem, jak wyżej, ale wywala błąd. Szukałem ale nic nie znalazłem dlatego proszę Was o pomoc.

Pozdrawiam.

0

błąd dotyczący stworzenia kontrolki w innym wątku?

lblFailt.Invoke(new updateText(UpdateText), invoke);
zrob cos podobnego tylko ze służące do zmiany właściwości kontrolki
Chyba o to chodzi?

0

Wielkie dzięki dark_astray :)
Wymyśliłem coś takiego i działa:

btnStart.Invoke(new updateButton(UpdateButtonStart));
btnStop.Invoke(new updateButton(UpdateButtonStop));

ale mam znów problem i jeśli to nie problem znów podepnę pod ten temat.
Próbuję sformatować stringa do postaci takiej jakiej chcę, a mianowicie w zmiennej time w funkcji private void btnStart_Click(object sender, EventArgs e) otrzymuję taką wartość: 4,7544444 i chcę aby mi to zaokrąglało do 5. Próbowałem już wielu rzeczy między innymi coś takiego:

                string timeImpulses = string.Format("{0:0}",time);

i wywala błąd. Ja wiem, że to jest banalny problem ale nie mogę sobie z tym w żaden sposób poradzić :/. Za pomoc z góry dziękuję.

0

Math.Round(double.Parse(zmienna_string), 5);
chyba tak powinno być ok.

0

hmm, wydaje mi się, że jednak to nie jest to, ponieważ to, że na pisałem, że chcę zaokrąglić do 5 to tylko przykład, również dobrze może być 6, 8 czy 10. Z tego co piszesz to rozumiem, że to by zaokrąglało tylko do pięciu, no chyba, że się mylę? Potrzebuję coś takiego aby zaokrąglało do dowolnej liczby a nie tylko do pięciu.

0

int do_ilu_miejsc_zaokraglic = ...;
Math.Round(double.Parse(zmienna_string), do_ilu_miejsc_zaokraglic);
ten drugi parametr mowi do ilu miejsc zaokraglac

0

Wybacz ale teraz już całkiem nie rozumiem. Mnie interesuje tylko i wyłącznie zaokrąglanie do liczby całkowitej. Ja wiem, że to jest pewnie banalnie proste ale jakoś nie potrafię tego przetrawić.
Chcę aby w zmiennej: string timeImpulses była już wartość zaokrąglona, którą mógłbym wykorzystać dalej. Jeśli to nie problem to bardzo bym prosił o łapatologiczne wytłumacznie tego problemu ;)
Pozdrawiam

0

ja zrozumiałem że chcesz zaokrąglać do X miejsc po przecinku. :D

jeżeli do całości to wystarczy Math.Round(wartosc);
zostanie zwrócona wartosć zaookrąglona

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