Nevím proč, dělám, co je v mých silách, ale bez kloudného výsledku. Mám program se sériovým portem. Vysílám data v pravidelných intervalech (jedním časovačem), přijímám data a kontroluju je (CRC, apod.). Na statistické účely a na kontrolu spojení jsem zřídil druhý časovač, který měří timeout. Logika je prostá: na tik hlavního časovače odešlu data, zároveň zastavím hlavní časovač a spustím časovač timeoutu. V události přijetí dat na portu, po jejich kontrole, zastavím timeout a spustím hlavní časovač. Problém je v tom, že se mi nedaří spustit časovač správně, protože ho spouštím z vlákna sériového portu a jeho handler se nepřihlásí, tj. jako by neměl handler, tzn. další odeslání dat už nenastane. Zkusil jsem to přes události, ale ani tak to nejde. Můj poslední pokus ve zkratce uvádím níže. Dotaz tedy zní: jak správně ovládat časovač z jiného vlákna?
//Delegates and events
delegate void StopTimeoutDelegate(System::Object^ sender, EventArgs^ e);
public: event StopTimeoutDelegate^ StopTimeout;
delegate void StartTimeoutDelegate(System::Object^ sender, EventArgs^ e);
public: event StartTimeoutDelegate^ StartTimeout;
//private: System::Void timerMain_Tick(System::Object^ sender, EventArgs^ e)
{
//Něco jako serialPort1->Send(data)
//Spuštění timeoutu
StartTimeout(this, e);
}
//private: System::Void timerTimeout_Tick(System::Object^ sender, EventArgs^ e)
{
StopTimeout(this, e);
}
//serialPort handler při přijetí dat
private: System::Void serialPortDataRecieved(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
//Načtení dat do bufferu (globálního)
Thread^ Recieve = gcnew Thread(gcnew ThreadStart(this, &Form1::RecieveThread));
Recieve->Start();
}
//Vlákno pro kontrolu dat
private: System::Void RecieveThread()
{
//Kontrola CRC v bufferu
if(CRCCheck())
{
EventArgs^ ea = gcnew EventArgs();
StopTimeout(this, ea);
}
}
//Handler pro zastavení timeoutu a spuštění hlavního časovače
private: void StopTimeoutEventHandler(System::Object^ sender, EventArgs^ e)
{
timerTimeout->Stop();
timerMain->Start();
}
//Handler pro spuštění timeoutu a zastavení hlavního časovače
private: void StartTimeoutEventHandler(System::Object^ sender, EventArgs^ e)
{
timerMain->Stop();
timerTimeout->Start();
}
Vše funguje až do chvíle, kdy v pořádku přijmu a zkontroluju data. V případě chyby CRC nebo bez odpovědi se střídají hlavní časovač s časovačem timeoutu.