Diskuze: c# form - vytvoření timeoutu při sériové komunikaci
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Odpovídá na Michaal.K
ostrozan:21.3.2016 15:40
ostrozan:21.3.2016 15:40
Při odeslání spusť časovač.
Při příjmu ho zastav.
Při přetečení vyhoď chybu.
Jinak kolik dat přijímáš, že čekáš 300 ms?
Při 19200 bd příjmeš za tu dobu cca 500 bajtů.
Akceptované řešení
+20 Zkušeností
+2,50 Kč
+20 Zkušeností
+2,50 Kč
Odpovídá na ostrozan
Michaal.K:22.3.2016 13:56
Michaal.K:22.3.2016 13:56
Ahoj,
díky za rady s timeoutem, vytvořil jsem ho pomocí timeru.
Objevil se mi jiný problém a nechci zakládat nové téma. Teď mi program
hází chybu:
Nelze volat funkci Invoke nebo BeginInvoke pro ovládací prvek, dokud není vytvořen popisovač okna.
A nevím co stím. Děje se to v tříde settingsform(je to form s nastavením), když formulář otevřu podruhé a stisknu tlač. Test připojení (metoda buttonTest_Click). Chyba nastane v comm_OnTimedEvent. Zkrácený kód třídy settingsform:
Communication comm = Communication.Instance;
public SettingsForm(MainForm form)
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.FixedDialog; // Zakaz zmeny velikosti
comm.OnSerialDataReceived += new Communication.DataReceivedEventHandler(comm_OnSerialDataReceived);
comm.OnTimedEvent +=new Communication.TimedEventEventHandler(comm_OnTimedEvent);
}
void buttonTest_Click(object sender, EventArgs e)
{
Button buttonAkt = (Button)sender; // Zjisteni na ktery button se kliklo
var tabConParent = buttonAkt.Parent.Parent; // Zjisteni rodice(zalozka tabControl) buttonu na ktery se kliklo
List<ComboBox> allCombos = new List<ComboBox>(); // Ulozeni vsech comboboxu
allCombos.AddRange(GetComboBoxes((Control)tabConParent)); // Ulozi vsechny comboboxy v dane zalozce tabControl
comm.serialPorts[tabConParent.TabIndex].BaudRate = Convert.ToInt32(allCombos[0].SelectedItem); // Do listu serialPorts ulozim aktualne nastavene hodnoty z comboBoxu
comm.serialPorts[tabConParent.TabIndex].Parity = (Parity)Enum.Parse(typeof(Parity), allCombos[1].Text);
comm.serialPorts[tabConParent.TabIndex].StopBits = (StopBits)Enum.Parse(typeof(StopBits), allCombos[2].Text);
comm.ConnectionTest(comm.serialPorts[tabConParent.TabIndex]); // Zavolam test pripojeni
}
void comm_OnSerialDataReceived(SerialPort comPort, string data)
{
this.Invoke(new EventHandler(delegate
{
Form frm = Application.OpenForms["SettingsForm"];
if (frm == null) // Zjistim jestli je aktivni SettingsForm pokud ano pokracuji dal
return; // Ukoncim metodu pokud neni aktivni form, abych nezapisoval do data do prvku ktery neni vytvoren!!
int indexPortu = comm.serialPorts.IndexOf(comPort); // Index portu v tabControl a listu serialPorts
var tabConParent = tabControl1.TabPages[indexPortu]; // Zalozka tabPages kde bylo stisknuty button Test pripojeni
var gbTestAkt = tabConParent.GetContainerControl().ActiveControl.Parent; // Aktualni groupBox v dane zalozce tabPages
TextBox textBoxAkt = new TextBox(); // Ulozeni TextBoxu
textBoxAkt = GetTextBox((Control)gbTestAkt); // Ulozi TextBox v dane zalozce tabControl a groubBoxu
textBoxAkt.Font = new Font("Microsoft Sans Serif", 8);
textBoxAkt.Text = data; // Zapsani prijatych dat
textBoxAkt.TextAlign = HorizontalAlignment.Center; // Zarovnani textu na stred
textBoxAkt.BackColor = Color.GreenYellow;
}));
}
// Vyvola se tato metoda pokud dojde k preteceni casovace -> Timeout komunikace
void comm_OnTimedEvent()
{
this.Invoke(new EventHandler(delegate
{
int indexTabPage = tabControl1.SelectedIndex; // Index aktualni zalozkt v tabControl a listu serialPorts
var tabConParent = tabControl1.TabPages[indexTabPage]; // Zalozka tabPages kde bylo stisknuty button Test pripojeni
var gbTestAkt = tabConParent.GetContainerControl().ActiveControl.Parent; // Aktualni groupBox v dane zalozce tabPages
TextBox textBoxAkt = new TextBox(); // Ulozeni TextBoxu
textBoxAkt = GetTextBox((Control)gbTestAkt); // Ulozi TextBox v dane zalozce tabControl a groubBoxu
textBoxAkt.Font = new Font("Microsoft Sans Serif", 8, FontStyle.Bold);
textBoxAkt.Text = "Časový limit operace vypršel!";
textBoxAkt.TextAlign = HorizontalAlignment.Center;
textBoxAkt.BackColor = Color.DarkRed;
}));
}
a tady jsou úpravy třídy communication:
public delegate void TimedEventEventHandler(); // Deklarace delagata, ktery bude slouzit jako predpis metody predstavujici reakci na udalost (handler)
public event TimedEventEventHandler OnTimedEvent; // Deklarace udalosti
private System.Timers.Timer timerTimeout;
// Metoda, ktera provede nastaveni timeru pro timeout komunikace
private void SetTimerTimeout()
{
timerTimeout = new System.Timers.Timer(500);
timerTimeout.Elapsed += new System.Timers.ElapsedEventHandler(timerTimeout_Elapsed); // Pridani udalosti, ktera je vyvolana pokud dojde k preteceni casovace
}
// Metoda, ktera se vykona pri preteceni casovace
void timerTimeout_Elapsed(object sender, EventArgs e)
{
System.Timers.Timer timerTimeout = (System.Timers.Timer)sender;
timerTimeout.Enabled = false; // Zastavim timer
Form frm = Application.OpenForms["SettingsForm"];
if (frm != null) // Zjistim jestli je aktivni SettingsForm pokud ano zavolam metodu
OnTimedEvent();
else
MessageBox.Show("Časový limit operace vypršel!", MainForm.appName, MessageBoxButtons.OK, MessageBoxIcon.Error);
Disconnect(); // Zavru vsechny porty
}
public void ConnectionTest(SerialPort comPort)
{
SetTimerTimeout(); // Nastaveni parametru timeru
ConnectedPort(comPort); // Otevru dany seriovy port
int adrPortuList = serialPorts.IndexOf(comPort); // Zjistim index daneho serioveho portu v listu serialPorts
WriteData(adrPortuList, "Test"); // Vyslu testovaci retezec
timerTimeout.Enabled = true; // Zapnu timer
}
Díky za pomoc
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.
Zobrazeno 3 zpráv z 3.