www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Pošiljanje števil po RS-232
Pojdi na stran Prejšnja  1, 2, 3
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Periferija
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
gaborp
Član
Član



Pridružen-a: Sob 16 Jul 2005 9:54
Prispevkov: 63
Aktiv.: 0.27
Kraj: Škofja Loka / Tržič

PrispevekObjavljeno: Sob Okt 06, 2007 1:04 pm    Naslov sporočila:   Odgovori s citatom

Vzrok problema je v multithreadingu. Gre se zato, da metode ali lastnosti kontrole nemoreš klicati iz katerega koli threada. Klici so dovoljeni samo iz threada v katerem je bila kontrola kreirana.

Pravilna rešitev problema je z uporabo Control.Invoke oz. control.BeginInvoke Metode. Opisana je v tukaj.

Koda:

private delegate void SafeUpdateLabelDelegate(Label lbl, string newText);

        /// <summary>
        /// Posodobi Text lastnost labele.
        /// </summary>
        /// <param name="lbl">
        /// Labela, kateri želimo spremeniti Text lastnost.
        /// </param>
        /// <param name="newText">
        /// Tekst, ki ga želimo vpisati v lbl.Text.
        /// </param>
        private void UpdateLabel(Label lbl, string newText)
        {
            lbl.Text = newText;
        }

        /// <summary>
        /// Posodobi Text lastnost labele v thread safe načinu.
        /// </summary>
        /// <param name="lbl">
        /// Labela, kateri želimo spremeniti Text lastnost.
        /// </param>
        /// <param name="newText">
        /// Tekst, ki ga želimo vpisati v lbl.Text.
        /// </param>
        private void SafeUpdateLabel(Label lbl, string newText)
        {
            // Preveri ali je potrebno uporabiti Invoke metodo
            if (lbl.InvokeRequired)
            {
                // Če kontrola, na kateri želimo izvesti poeracijo pripada drugemu threadu
                // uporabi Invoke metodo, drugače operacijo izvedi normalno
                lbl.BeginInvoke(new SafeUpdateLabelDelegate(UpdateLabel), lbl, newText);
            }
            else
                UpdateLabel(lbl, newText);
        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Preberi podatke
            string data = comport.ReadExisting();

            // posodobi labelo v thread safe načinu
            SafeUpdateLabel(lblData, data);
        }

Za več informacij pa uporabi Google s ključnimi besedami: .NET Invoke, .NET delegate
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
gkrusi
Član
Član



Pridružen-a: Tor 24 Jul 2007 17:22
Prispevkov: 811
Aktiv.: 3.72
Kraj: Ptuj

PrispevekObjavljeno: Sob Okt 06, 2007 11:34 pm    Naslov sporočila:   Odgovori s citatom

Najlepša ti hvala gaborp Very Happy . Sedaj moram to le še naštudirat in vnesti v svoj program Confused .
_________________
Zakaj bi bilo preprosto, če je lahko zakomplicirano???
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo Obišči avtorjevo spletno stran
gkrusi
Član
Član



Pridružen-a: Tor 24 Jul 2007 17:22
Prispevkov: 811
Aktiv.: 3.72
Kraj: Ptuj

PrispevekObjavljeno: Sre Okt 10, 2007 6:49 pm    Naslov sporočila:   Odgovori s citatom

Text v labeli mi je sedaj s pomočjo gaboarpovega primera uspelo urejati Razz , še vedno pa imam težavo s to prekinitvijo.
Spreminjati moram namreč tudi text v RichTextBox-u. Da pa vse ni tako "preprosto", moram spreminjati le točno določen znak. Kako se spremeni točno določen znak, v "normalnih" okoliščinah vem. Ne vem pa kako sploh sremeniti text v RichTextBoxu iz prekinitve serijskega porta (brez napake seveda).

Na googlu in msdn-ju mi ni uspelo najti nič kaj primernega, če poskusim invoke metodo prilagoditi RichTextBoxu, pa se mi pojavi napaka (morda sem kaj narobe naredil).
Bi morala zadeva z invoke metodo delati tudi pri RichTextBoxu? Rolling Eyes

Spet prosim za kakšno rešitev in še bolje za primer. Hvala!
Če nisem bil dovolj jasen, pa prosim za opozorilo, da še kaj dodam.

_________________
Zakaj bi bilo preprosto, če je lahko zakomplicirano???
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo Obišči avtorjevo spletno stran
gaborp
Član
Član



Pridružen-a: Sob 16 Jul 2005 9:54
Prispevkov: 63
Aktiv.: 0.27
Kraj: Škofja Loka / Tržič

PrispevekObjavljeno: Sre Okt 10, 2007 11:30 pm    Naslov sporočila:   Odgovori s citatom

Z Invoke metodo bi moralo delovati. Če bi prilimal kodo bi ti veliko lažje pomagal. Pokaži vsaj del, na katerega se sklicuješ v stavku:
gkrusi je napisal/a:
Kako se spremeni točno določen znak, v "normalnih" okoliščinah vem.

Kaj si mislil s tem:
gkrusi je napisal/a:
moram spreminjati le točno določen znak

Ti jutri spišem primer.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
gkrusi
Član
Član



Pridružen-a: Tor 24 Jul 2007 17:22
Prispevkov: 811
Aktiv.: 3.72
Kraj: Ptuj

PrispevekObjavljeno: Čet Okt 11, 2007 4:12 pm    Naslov sporočila:   Odgovori s citatom

Sem sedaj poskusil sestavit preimer z RichTextBox-om in SerialPortom in je zadeva sedaj, ko sem jo tretjič sestavil uspela Very Happy (čeprav še nisem popolnoma prepričan, da vem kako)!

Bom sedaj še malo zadevo preizkusil in se spet javim, ko mi kaj ne bo delalo Laughing .
Tako, da spet havala zaenkrat, posebej tebi gaborp!


Pred tem pa sem sestavil sem en primer, kako bi morala zadeva delovati. Ga vseeno prilagam, za morebitne "radovedneže".
V primeru:
-v numericUpDown1 vpišem začetni položaj, na katerem se število, ki ga spreminjam nahaja
-v numericUpDown2 vpišem število, ki naj nadomesti prejšnje število (v "originalnem" progamu bodo verjetno uporabljeni le znaki: 0, 1, presledek, enter, ')
-ob pritsku na tipko button1, se označeno število zamenja z želenim

Koda:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            richTextBox1.Text = "0123\n0123\n0123\n0123\n0123";  // vpiše začetno besedilo v richTextBox1
        }

        private void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.SelectionStart = (int)numericUpDown1.Value;  //postavi kurzor na zahtevan položaj
            richTextBox1.SelectionLength = 1;                         //označi en znak za kurzorjem
            richTextBox1.SelectedText = "" + numericUpDown2.Value;    //zamenja označen znak
        }
    }
}


Enak primer, ki vsebuje tudi SerialPort pa trenutno izgleda tako:
Koda:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            richTextBox1.Text = "0123\n0123\n0123\n0123\n0123";     // vpiše začetno besedilo v richTextBox1
            serialPort1.Open();     // vzpostavi
        }

        // Invoke:
        private delegate void SafeUpdateRichTextBoxDelegate(RichTextBox richTextBox1, string newText);

        private void UpdateRichTextBox(RichTextBox richTextBox1, string newText)
        {
            richTextBox1.SelectionStart = (int)numericUpDown1.Value;    //postavi kurzor na zahtevan položaj
            richTextBox1.SelectionLength = 1;                           //označi en znak za kurzorjem
            richTextBox1.SelectedText = newText;                        //zamenja označen znak
        }

        private void SafeUpdateRichTextBox(RichTextBox richTextBox1, string newText)
        {
            // Preveri ali je potrebno uporabiti Invoke metodo
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.BeginInvoke(new SafeUpdateRichTextBoxDelegate(UpdateRichTextBox), richTextBox1, newText);
            }
            else
                UpdateRichTextBox(richTextBox1, newText);
        }

        // glavni program:
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = serialPort1.ReadExisting();       // prebere podatke iz serial porta
            SafeUpdateRichTextBox(richTextBox1, data);      // spremeni besedilo
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            serialPort1.Close();    // prekine povezavo
        }
    }
}



Primer.jpg
 Opis:
 Velikost datoteke:  9.49 KB
 Pogledana:  3518 krat

Primer.jpg



_________________
Zakaj bi bilo preprosto, če je lahko zakomplicirano???
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo Obišči avtorjevo spletno stran
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Periferija Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran Prejšnja  1, 2, 3
Stran 3 od 3

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 492 dni


Powered by phpBB © 2001, 2005 phpBB Group