 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
gaborp Član

Pridružen-a: Sob 16 Jul 2005 9:54 Prispevkov: 63 Aktiv.: 0.27 Kraj: Škofja Loka / Tržič
|
Objavljeno: Sob Okt 06, 2007 1:04 pm Naslov sporočila: |
|
|
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 |
|
 |
gkrusi Član



Pridružen-a: Tor 24 Jul 2007 17:22 Prispevkov: 811 Aktiv.: 3.72 Kraj: Ptuj
|
Objavljeno: Sob Okt 06, 2007 11:34 pm Naslov sporočila: |
|
|
Najlepša ti hvala gaborp . Sedaj moram to le še naštudirat in vnesti v svoj program .
_________________ Zakaj bi bilo preprosto, če je lahko zakomplicirano??? |
|
Nazaj na vrh |
|
 |
gkrusi Član



Pridružen-a: Tor 24 Jul 2007 17:22 Prispevkov: 811 Aktiv.: 3.72 Kraj: Ptuj
|
Objavljeno: Sre Okt 10, 2007 6:49 pm Naslov sporočila: |
|
|
Text v labeli mi je sedaj s pomočjo gaboarpovega primera uspelo urejati , š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?
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 |
|
 |
gaborp Član

Pridružen-a: Sob 16 Jul 2005 9:54 Prispevkov: 63 Aktiv.: 0.27 Kraj: Škofja Loka / Tržič
|
Objavljeno: Sre Okt 10, 2007 11:30 pm Naslov sporočila: |
|
|
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 |
|
 |
gkrusi Član



Pridružen-a: Tor 24 Jul 2007 17:22 Prispevkov: 811 Aktiv.: 3.72 Kraj: Ptuj
|
Objavljeno: Čet Okt 11, 2007 4:12 pm Naslov sporočila: |
|
|
Sem sedaj poskusil sestavit preimer z RichTextBox-om in SerialPortom in je zadeva sedaj, ko sem jo tretjič sestavil uspela (č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 .
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
}
}
}
|
Opis: |
|
Velikost datoteke: |
9.49 KB |
Pogledana: |
3518 krat |

|
_________________ Zakaj bi bilo preprosto, če je lahko zakomplicirano??? |
|
Nazaj na vrh |
|
 |
|
|
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
|