Com port работа с несколькими

des1roer
Дата: 10.06.2014 08:50:26
в общем и целом умею работать с ком портом. но необходимо организовать перебор указанных ком портов и все их опросить
+
#region comport
        private void SelectCom()  //com port
        {
            try
            {
                NpgsqlConnection conn = new NpgsqlConnection(("Server=" + list[0] + ";Port=" + list[1] + ";User Id=" + list[2] + ";Password=" + list[3] + ";Database=" + list[4] + ";"));  //
                string sql = " SELECT  \"ID_TagName\", \"ID_RealHardWare\",   \"F_ParseFunction\",   \"F_ComQuery\",   \"F_AnswerLenght\",   \"F_AnswerKey\",   \"F_AnswerKeyPosition\",   \"F_ComPort\",   \"F_ComPortIPAdress\",   \"F_ComPortBaudRate\",   \"F_ComPortParity\",   \"F_ComPortDataBits\",   \"F_ComPortStopBit\",   \"F_ComPortFlowControl\",   \"F_ComPortTimeOut\" ,  \"ID_HardWareTag\",   \"F_OPCServerName\",   \"F_IDOPCTag\", \"F_TagReadTime\",   \"Transmit\",   \"F_RealHardWare_ID\" FROM  \"SC_Tag\".\"T_TagName\" as tn,\"SC_Tag\".\"T_HardWareTag\" as hw , \"SC_Tag\".\"T_RealHardWare\" as rh where  rh.\"ID_RealHardWare\" = hw.\"F_RealHardWare_ID\"  and tn.\"F_HardWare_ID\" = hw.\"F_TagName_ID\"   and \"F_ServerName\"  =\'" + Environment.MachineName + "\' and \"F_ComPortIPAdress\" = \'127.0.0.1\' ";
                //   string sql = "  SELECT \"F_name\", \"F_OPCServerName\", \"F_IDOPCTag\", \"F_TagReadTime\",  \"ID_TagName\"   FROM \"SC_Tag\".\"T_TagName\" as tn, \"SC_Tag\".\"T_HardWareTag\" as hw  where tn.\"F_HardWare_ID\" = hw.\"ID_HardWareTag\"    and \"F_ServerName\"  =\'" + Environment.MachineName + "\' ";

                NpgsqlDataAdapter da3 = new NpgsqlDataAdapter(sql, conn);
                //textBox1.Text = sql;
                ds3.Reset();
                da3.Fill(ds3);
                dt3 = ds3.Tables[0];
                dataGridView3.DataSource = dt3;
                if (ds3.Tables[0] != null)
                {

                    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.timer4.Interval = min;
                    // Таймер
                    Timer timer = new Timer();
                    // Порт
                    //      SerialPort port = new SerialPort("COM2", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One); 
                    for (int xx = 0; xx < ds3.Tables[0].Rows.Count; ++xx)
                    {
                       

                    }
                    // Задаем интервал таймеру
                    timer4.Interval = min;
                    // Подписываемся на тики таймера
                    timer4.Tick += new EventHandler(timer1_Tick);
                    // Стартуем таймер
                    timer4.Start();
                }
        
            }
            catch (Exception msg)
            {
                MessageBox.Show(msg.ToString() + " Select()");
                this.file.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss\t Select()") + msg.ToString());
                this.file.Flush();
                return;
            }
        }
        private void timer4_Tick(object sender, EventArgs e)
        {
            for (int xx = 0; xx < ds3.Tables[0].Rows.Count; ++xx)
            {
                string com = "COM" + dt3.Rows[xx][7];
                send = dt3.Rows[xx][3].ToString() + "\r";
                port = new SerialPort(com, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
                // Открываем порт
                if (port.IsOpen)
                {
                    // Если порт открыт, значит какой-то косяк, девайс не ответил, здесь обрабатываем

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

                // Открываем
                port.Open();

                port.Write(send);
            }
        }

        int icom = 0;
        // Пришли данные
        void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
           

                for (int xx = 0; xx < ds3.Tables[0].Rows.Count; ++xx)
                {
                   
                  

                    System.Threading.Thread.Sleep(100);
                    // Получаем пришедшие данные
                    string indata = port.ReadExisting();

                    // Чето с ними делаем
                    //MessageBox.Show(icom++.ToString() + " " + indata);
                    //  textBox1.Text = indata;
                    //   this.Text = i++.ToString();
                    NpgsqlConnection conn = new NpgsqlConnection(("Server=" + list[0] + ";Port=" + list[1] + ";User Id=" + list[2] + ";Password=" + list[3] + ";Database=" + list[4] + ";"));
                    conn.Open();
                    String Mystr = ("INSERT INTO " + list[5] + "(\"F_TagName_ID\",\"F_Value\",\"F_Date\")  VALUES (" + dt3.Rows[xx][0].ToString() + ",\'" + indata + "\',\'" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\'   )");
                    //  MessageBox.Show(Mystr);
                    textBox1.Text = Mystr;
                    NpgsqlCommand command = new NpgsqlCommand(Mystr, conn);
                    int rowsaffected;
                    rowsaffected = command.ExecuteNonQuery();
                    conn.Close();

                    /*    if (port.BytesToRead > 0)
                        {
                            byte[] data = new byte[port.BytesToRead];
                            port.Read(data, 0, port.BytesToRead);
                            ASCIIEncoding ascii = new ASCIIEncoding();
                            String decoded = ascii.GetString(data);
                            MessageBox.Show ( decoded + " i: " + i++.ToString());


                        }*/
                    // Закрываем порт
                    if (port.IsOpen)
                    {
                        // Если порт открыт, значит какой-то косяк, девайс не ответил, здесь обрабатываем

                        // Закрываем
                        port.Close();
                    }
                }
            }
            catch (Exception msg)
            {
                  MessageBox.Show(msg.ToString() + "TagIntoNPG()");
                this.file.WriteLine(DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss\t TagIntoNPG()") + msg.ToString());
                this.file.Flush();
                // AddLog(msg.ToString());
                throw;
            }
        }
        #endregion

D129
Дата: 10.06.2014 11:57:08
des1roer


Очень смутно у вас написано, и без понимания.
Таймер вот разве можно так использовать - создавать новый в цикле, присваивать обработчик, запускать и выходить из цикла.....

Какую вообще пробему вы решаете таким образом?

Что же касается всей задачи - то чтобы предложить что-то оптимальное надо знать больше про ваши требования.

Например - эта апликация все время запущена, или должна подняться - сделать работу -упасть?

А между обработками портов база данных может измениться?
(Мне кажется что врядли - но всякое бывает...)

И так далее.

Если вы учитесь - попробуйте подумать об обьекте, который может выполнить всю работу с любым ком портом сам. Если у вас будет такой обьект, то вы сможете организовать коллекцию таких обьектов, а не писать замусоренные подключениями-отключениями циклы....
Где-то в степи
Дата: 10.06.2014 12:34:34
des1roer,
соглашусь с коллекцией наблюдателей, принцип хоть отсюда http://stackoverflow.com/questions/15124132/serial-port-polling-and-data-handling, над таймером тоже посмеялся ))
des1roer
Дата: 10.06.2014 12:37:48
дело такое - сервис получает список компортов, получает что он должен отправить на эти компорты. затем что получил то пишет в базу. если с обработкой опс серверов проблем не возникло (там в цикле довольно просто оббежать все порты), то тут необходимо создавать это событие eventhandler (вот тут то и главная загвоздка) к одному то подцепиться проблем не возникает, необходимо в цикле перебирать все полученные компорты\что посылать
des1roer
Дата: 10.06.2014 12:39:39
таймер нужен чтобы постоянно опрашивать
Где-то в степи
Дата: 10.06.2014 12:45:21
des1roer,
наблюдатель ( как единица) должен быть самодостаточным, он должен сам знать что ему делать в каких ситуациях
куда писать и что отвечать, это все естественно присваивается ему ( учим его как поступать) при инициализации
des1roer
Дата: 10.06.2014 12:52:21
ну я ему даю значение ком порта, что посылать пишу, таймер устанавливаю. но не известно будет ли один ком порт, а сколько их будет не знаю
Где-то в степи
Дата: 10.06.2014 12:59:30
des1roer,
тут и напрашивается ответ, если наблюдатели изолированы между собой ( ну может в екшене где пересекаются с аккумулятором)
на каждый порт вешаем наблюдателя: 100 портов 100 наблюдателей
des1roer
Дата: 10.06.2014 13:14:17
это крайне плохое решение мне кажется. есть 1 сервис - он может опрашивать все опс сервера что к нему подключены, все железяки по ip, необходимо еще и все com порты просматривать. т.е. как нибудь в цикле перебирать к какому порту цепляться и что посылать
D129
Дата: 10.06.2014 13:20:50
des1roer
это крайне плохое решение мне кажется.

Обоснуйте.
У вас будет коллекция обьектов, которые могут быть подключены к своим портам, могут быть не подключены - это все пишется.

Во внешнем коде будет только перебор этих обьектов (любого их количества).
Что вы боитесь растратить? Память?