потоки в C#

des1roer
Дата: 20.06.2014 07:15:38
дело такое - опрашиваю ком порты. есть функция и класс, отвечающие за разные методы.
приходится ставить thread.sleep() чтобы получить значение с ком порта, потому что сразу они не приходят.
так вот - все это дело крутится в таймере.
пытаюсь выключить таймер - он мне ругается.
как остановить thread.sleep по клику?
Алексей К
Дата: 20.06.2014 07:23:43
des1roer
дело такое - опрашиваю ком порты. есть функция и класс, отвечающие за разные методы.
приходится ставить thread.sleep() чтобы получить значение с ком порта, потому что сразу они не приходят.
так вот - все это дело крутится в таймере.
пытаюсь выключить таймер - он мне ругается.
как остановить thread.sleep по клику?
Зачем таймер? У компорта есть события.
des1roer
Дата: 20.06.2014 07:30:44
и ? мне нужно поинтервально опрашивать его
des1roer
Дата: 20.06.2014 07:31:49
может можно узнать состояние потока и запустить его не ожидая слип
Алексей К
Дата: 20.06.2014 07:53:10
des1roer
и ? мне нужно поинтервально опрашивать его
Обычно поинтервально делают запрос+ответ.

А если девайс постоянно шлёт данные в порт, без запроса, то лучше принимать данные по событию.

автор
приходится ставить thread.sleep() чтобы получить значение с ком порта, потому что сразу они не приходят.
Этот момент проясни, обычно это решается через read timeout в порте.
des1roer
Дата: 20.06.2014 08:03:49
readtimeout не помогает. пробовал
_COM.ReadTimeout = timeout;
_COM.WriteTimeout = timeout;
да идет запрос-ответ. в общем, если не привязываться к технологии возможно прибить слип? хотя, может я таймаут неправильно выставил? но вот сколько не менял - разницы ровным счетом никакой
Pallaris
Дата: 20.06.2014 08:19:16
des1roer,

Тайм аут нужно задавать перед открытием порта. В милисекундах
des1roer
Дата: 20.06.2014 08:22:23
вот усечченный вариант, скелет ак сказать, но суть ясна
+


namespace ServiceUniOPc
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
           
        }


        #region tcpconnect
        private void SelectTcp()  //com port
        {
           this.timer1.Start();           
        }


        private void timer1_Elapsed(object sender, EventArgs e)
        {
		for (int i = 0; i < ds.Tables[0].Rows.Count; i++)               
                        Connect(dt.Rows[i][1].ToString(), dt.Rows[i][2].ToString() + "\r", Convert.ToInt32(dt.Rows[i][3]), i);
           
        }

        void Connect(String server, String message, Int32 port, Int32 id)
        {
            try
            {
                // Create a TcpClient.
                // Note, for this client to work you need to have a TcpServer 
                // connected to the same address as specified by the server, port
                // combination.
                TcpClient client = new TcpClient(server, port);

                // Translate the passed message into ASCII and store it as a Byte array.
                Byte[] data = Encoding.UTF8.GetBytes(message);
                // Get a client stream for reading and writing.
                

                NetworkStream stream = client.GetStream();

                // Send the message to the connected TcpServer. 
                stream.Write(data, 0, data.Length);

            

                // Receive the TcpServer.response.

                // Buffer to store the response bytes.
                data = new Byte[256];

                Thread.Sleep(300);
                

                // String to store the response ASCII representation.              

                // Read the first batch of the TcpServer response bytes.
                Int32 bytes = stream.Read(data, 0, data.Length);
                responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
  
                // Close everything.
                stream.Close();
                client.Close();

            }
			
        }        
        #endregion 


        #region comport
        private void SelectCom()  //com port
        {
                        InitAll();        
        }
      


        private void InitAll()
        {
               allListeners = new List<OneCOMSpectator>();

                for (int xx = 0; xx < ds3.Tables[0].Rows.Count; ++xx)
                {
                    string com = "COM" + dt3.Rows[xx][1];
                    string send = dt3.Rows[xx][3].ToString() + "\r";
                    string idcom = dt3.Rows[xx][0].ToString();
                    int BaudRate = Convert.ToInt32(dt3.Rows[xx][2]);
                    string parity = dt3.Rows[xx][10].ToString();
                    int databit = Convert.ToInt32(dt3.Rows[xx][11]);
                    double stopbit = Convert.ToDouble(dt3.Rows[xx][12]);
                    string flowcontrol = dt3.Rows[xx][13].ToString();
                    int timeout = Convert.ToInt32(dt3.Rows[xx][14]);
                    string parseFunc = dt3.Rows[xx][4].ToString();
                    allListeners.Add(new OneCOMSpectator(com, BaudRate, send, idcom, parity, databit, stopbit, flowcontrol, timeout, parseFunc));
                }
                min = Convert.ToInt32(dt3.Rows[0][14]);
                for (int i = 0; i < ds3.Tables[0].Rows.Count; i++)
                {
                    if (Convert.ToInt32(dt3.Rows[i][14]) < min)
                        min = Convert.ToInt32(dt3.Rows[i][14]);
                }
               
                    this.timer3 = new System.Timers.Timer();
                    this.timer3.Enabled = true;
                    this.timer3.Interval = min;
                    this.timer3.Elapsed += new System.Timers.ElapsedEventHandler(this.timer3_Elapsed);
                    this.timer3.AutoReset = true;
                    this.timer3.Start();
         
          
        }

        private void timer3_Elapsed(object sender, EventArgs e)
        {
                foreach (OneCOMSpectator comListener in allListeners)
                {
                    comListener.TransferData();
                }

        }

        class OneCOMSpectator
        {
             
            SerialPort _COM;
            string DataToSend;
            string IdCom;
            string ParseGlob = "";

            internal OneCOMSpectator(string portNumber, int bodRate, string dataTosend, string idcom, string parity, int databit, double stopbit, string flowcontrol, int timeout, string parse)
            {
                IdCom = idcom;
                DataToSend = dataTosend;
                _COM = new SerialPort(portNumber, bodRate);

                if (parity.ToLower() == "none")
                    _COM.Parity = System.IO.Ports.Parity.None;
                else if (parity.ToLower() == "even")
                    _COM.Parity = System.IO.Ports.Parity.Even;
                else if (parity.ToLower() == "mark")
                    _COM.Parity = System.IO.Ports.Parity.Mark;
                else if (parity.ToLower() == "odd")
                    _COM.Parity = System.IO.Ports.Parity.Odd;
                else if (parity.ToLower() == "space")
                    _COM.Parity = System.IO.Ports.Parity.Space;

                _COM.DataBits = databit;

                if (stopbit == 0)
                    _COM.StopBits = StopBits.None;
                else if (stopbit == 1)
                    _COM.StopBits = StopBits.One;
                else if (stopbit == 1.5)
                    _COM.StopBits = StopBits.OnePointFive;
                else if (stopbit == 2)
                    _COM.StopBits = StopBits.Two;

                if (flowcontrol.ToLower() == "none")
                    _COM.Handshake = Handshake.None;
                else if (flowcontrol.ToLower() == "rts/cts" || flowcontrol.ToLower() == "rts\\cts")
                    _COM.Handshake = Handshake.RequestToSend;
                else if (flowcontrol.ToLower() == "xon/xof" || flowcontrol.ToLower() == "xon\\xof")
                    _COM.Handshake = Handshake.RequestToSendXOnXOff;
                else if (flowcontrol.ToLower() == "dtr/dsr" || flowcontrol.ToLower() == "dtr\\dsr")
                    _COM.Handshake = Handshake.XOnXOff;

                _COM.ReadTimeout = timeout;
                _COM.WriteTimeout = timeout;
                if (parse != "")
                    ParseGlob = parse;


                _COM.DataReceived += new SerialDataReceivedEventHandler(_COM_DataReceived);

            }

            void _COM_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                    Thread.Sleep(100);
                    // Пришли данные
                    String indata = _COM.ReadExisting();
                    indata = indata.Substring(0, indata.Length - 1);
                    String Mystr = "";
                    // Чето с ними делаем  

            }


            internal void TransferData()
            {
                try
                {
                    if (_COM.IsOpen)
                    {
                        // Если порт открыт, значит какой-то косяк, девайс не ответил, здесь обрабатываем

                        // Закрываем
                        _COM.Close();
                    }

                    // Открываем
                    _COM.Open();
                    _COM.Write(DataToSend);
                }
                catch 
                {
                    
                    return;
                }
            }
        }    
        #endregion

        #region start
        protected override void OnStart(string[] args)
        {

                      SelectTcp(); 
              
                    SelectCom();
             
                
           
        }
        #endregion

        #region stop
        protected override void OnStop()
        {
                if (this.timer1.Enabled) this.timer1.Stop();
               
                if (this.timer3.Enabled)  this.timer3.Stop();
            
        }
        #endregion

    }
}



des1roer
Дата: 20.06.2014 08:23:25
так и делаю
           IdCom = idcom;
                DataToSend = dataTosend;
                _COM = new SerialPort(portNumber, bodRate);

                if (parity.ToLower() == "none")
                    _COM.Parity = System.IO.Ports.Parity.None;
                else if (parity.ToLower() == "even")
                    _COM.Parity = System.IO.Ports.Parity.Even;
                else if (parity.ToLower() == "mark")
                    _COM.Parity = System.IO.Ports.Parity.Mark;
                else if (parity.ToLower() == "odd")
                    _COM.Parity = System.IO.Ports.Parity.Odd;
                else if (parity.ToLower() == "space")
                    _COM.Parity = System.IO.Ports.Parity.Space;

                _COM.DataBits = databit;

                if (stopbit == 0)
                    _COM.StopBits = StopBits.None;
                else if (stopbit == 1)
                    _COM.StopBits = StopBits.One;
                else if (stopbit == 1.5)
                    _COM.StopBits = StopBits.OnePointFive;
                else if (stopbit == 2)
                    _COM.StopBits = StopBits.Two;

                if (flowcontrol.ToLower() == "none")
                    _COM.Handshake = Handshake.None;
                else if (flowcontrol.ToLower() == "rts/cts" || flowcontrol.ToLower() == "rts\\cts")
                    _COM.Handshake = Handshake.RequestToSend;
                else if (flowcontrol.ToLower() == "xon/xof" || flowcontrol.ToLower() == "xon\\xof")
                    _COM.Handshake = Handshake.RequestToSendXOnXOff;
                else if (flowcontrol.ToLower() == "dtr/dsr" || flowcontrol.ToLower() == "dtr\\dsr")
                    _COM.Handshake = Handshake.XOnXOff;

                _COM.ReadTimeout = timeout;
                _COM.WriteTimeout = timeout;
                if (parse != "")
                    ParseGlob = parse;


                _COM.DataReceived += new SerialDataReceivedEventHandler(_COM_DataReceived);
//////////
    if (_COM.IsOpen)
                    {
                        // Если порт открыт, значит какой-то косяк, девайс не ответил, здесь обрабатываем

                        // Закрываем
                        _COM.Close();
                    }

                    // Открываем
                    _COM.Open();
                    _COM.Write(DataToSend);
                }
Pallaris
Дата: 20.06.2014 08:56:24
Не вижу, где у тебя чтение порта (не по событию). Назначение тайм аута - выбить эксепшн, если ты обратился к методу read, а он в течении времени не выдал данные