powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / потоки в C#
25 сообщений из 76, страница 2 из 4
потоки в C#
    #38675236
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К вы мой код-скелет видели? подскажите как вписать

Код: c#
1.
2.
3.
4.
5.
6.
    while (_COM.BytesToRead > 0)
                   {
                       _COM.Read(buf1, 0, 256);
                       string tmp = System.Text.Encoding.ASCII.GetString(buf1);
                       tmp_buf += tmp;
                   }


приходит полчисла и потом полчисла
...
Рейтинг: 0 / 0
потоки в C#
    #38675269
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roerАлексей К вы мой код-скелет видели? подскажите как вписатьТы определись сначала с протоколом, потом будешь вписывать. Один из вариантов примерно такой:
Код: c#
1.
2.
3.
// псевдокод
var length = comPort.ReadIntNumber();
var data = comport.ReadByteArray(length);
...
Рейтинг: 0 / 0
потоки в C#
    #38675295
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roerприходит полчисла и потом полчисла

полчисла да полчисла - будет целое число
...
Рейтинг: 0 / 0
потоки в C#
    #38675324
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не понял про протокол
...
Рейтинг: 0 / 0
потоки в C#
    #38675326
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про полчисла - интересно почему разрыв получается
...
Рейтинг: 0 / 0
потоки в C#
    #38675411
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roerпро полчисла - интересно почему разрыв получается
может в Autoexec.bat добавить строку serial_data_number_no_breake = true?
...
Рейтинг: 0 / 0
потоки в C#
    #38675436
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roer, а если серьезно...
устройство может слать вам данные какими угодно частями, не рассматривайте что к вам приходят числа, рассматривайте как поток данных. и SerialPort НИКАК НЕ ДОГАДАЕТСЯ что пришли ваши два числа. полагаю через TCP или UDP вам будет точно такой же поток данных приходить.

протокол - подразумевает что в этом потоке данных есть некоторые "маркеры" определяющие структуру данных, которые позволяют вам отделять числа друг от друга, эти разделители есть, вы приводили пример (в других темах форума).
вам в DataRecieve надо сперва собирать данные в строку, и после того как попадается разделитель - отрезать от неё нужный кусок и обрабатывать.

мне видится что конструкция "while (_COM.BytesToRead > 0)" в вашем случае не самый лучший вариант.

далее, использовать Thread.Sleep - тоже лажа
в классе объявите
EventWaitHandle wh = new AutoResetEvent(false);
... когда поток выполняет проверку нужно ли дальше работать вызывайте
wh.WaitOne() ; - поток уснет
а таймером, раз в 2..10 секунд - wh.Set() - и поток проснется
это же поможет когда нужно поток быстро остановить.
...
Рейтинг: 0 / 0
потоки в C#
    #38675456
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roer, вот упрощенный пример
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
    internal class MyComReader
    {
        private SerialPort port;
        private System.Timers.Timer timer;
        private System.Threading.Thread thread;
        readonly EventWaitHandle wh = new AutoResetEvent(false);
        private bool doWork;

        public void ThreadStart()
        {
            doWork = true;
            thread = new Thread(Execute);
            thread.Start();
            timer = new System.Timers.Timer(1000) {Interval = 10000};
            timer.Elapsed += timer_Elapsed;
        }

        public void ThreadStop()
        {
            doWork = false;
            wh.Set();
        }

        void Execute()
        {

            while (doWork)
            {
                if (port == null)
                {
                    port = new SerialPort("COM1", 2400);
                    port.DataReceived += port_DataReceived;
                }
                if(!port.IsOpen)
                    port.Open();

                wh.WaitOne();
            }
            if (port.IsOpen)
                port.Close();
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            wh.Set();
        }

        private string inData;
        void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;

            inData += sp.ReadExisting();

            // проверка, если в InData появилась полная строка - отрезаем кусок
            // и обрабатываем, а лучше в другой поток для обработки передаем
        }
    }
...
Рейтинг: 0 / 0
потоки в C#
    #38675458
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
6.
        public void ThreadStop()
        {
            doWork = false;
            timer.Stop();
            wh.Set();
        }
...
Рейтинг: 0 / 0
потоки в C#
    #38675468
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчик
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
        private string inData;

        void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;

            inData += sp.ReadExisting();

            // проверка, если в InData появилась полная строка - отрезаем кусок
            // и обрабатываем, а лучше в другой поток для обработки передаем
        }
    }

Плохо.
...
Рейтинг: 0 / 0
потоки в C#
    #38675476
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КПлохо.
аргументы?
у меня вот так уже больше года считывает данные с оборудования, пожаловаться не могу.
...
Рейтинг: 0 / 0
потоки в C#
    #38675477
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roerне понял про протоколЕщё раз, данные передаются блоками. Есть два основных способа получения блока:

1. Сначала прочитать из порта размер блока данных. Для этого надо прочитать, например, 4 байта и преобразовать их в Int32. Потом, зная размер блока, прочитать известное количество байт.

или

2. Читать из порта побайтно пока не встретится символ завершения блока.
...
Рейтинг: 0 / 0
потоки в C#
    #38675492
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикАлексей КПлохо.
аргументы?Есть решение проще.
Кифирчику меня вот так уже больше года считывает данные с оборудования, пожаловаться не могу.Это ничего не меняет.
...
Рейтинг: 0 / 0
потоки в C#
    #38675514
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во я как-то давно писал для считывателя электронных карт, может натолкнёт на какие-нибудь мысли.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
    public class CardReaderDevice : IDisposable
    {
        private static readonly byte[] _password = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

        private SerialPort _port = new SerialPort();
        private ByteCounter _frameIDGenerator = new ByteCounter();

        private CardReaderByteStaffing _byteStaffing = new CardReaderByteStaffing(
            FRAME_STAFFED_BYTE, 
            STAFFED_FRAME_STAFFED_BYTE
        );

        public CardReaderDevice()
        {
            _byteStaffing.AddToMap(FRAME_START, STAFFED_FRAME_START);
            _byteStaffing.AddToMap(FRAME_STOP, STAFFED_FRAME_STOP);
            DeviceInfo = null;
            Active = false;
        }

        public virtual void Dispose()
        {
            Close();
            _port.Dispose();
        }

        #region Open / Close

        public bool Active { get; private set; }
        public CardReaderDeviceInfo DeviceInfo { get; private set; }

        private void InitializePort(string portName)
        {
            _port.PortName = portName;
            _port.BaudRate = 9600;
            _port.DataBits = 8;
            _port.StopBits = StopBits.One;
            _port.Parity = Parity.None;
            _port.Handshake = Handshake.None;
            _port.ReadTimeout = 200;
        }

        public void Open(string portName)
        {
            Close();
            InitializePort(portName);
            CardReaderDeviceInfo deviceInfo;
            _port.Open();
            try
            {
                deviceInfo = ReadDeviceInfo();
                SwitchSignals(CardReaderSignals.BeeperDouble | CardReaderSignals.GreenBeeper);
            }
            catch
            {
                _port.Close();
                throw;
            }
            DeviceInfo = deviceInfo;
            Active = true;
        }

        public void Close()
        {
            if (Active == false)
                return;
            try
            {
                _port.Close();
            }
            catch { }
            DeviceInfo = null;
            Active = false;
        }

        public void Open()
        {
            StringBuilder err = new StringBuilder();
            foreach (string portName in SerialPort.GetPortNames())
            {
                try
                {
                    Open(portName);
                    break;
                }
                catch (Exception E)
                {
                    err.AppendLine(portName + ": " + E.Message);
                }
            }
            if (Active == false)
                throw new InvalidOperationException(
                    "Ошибка открытия считывателя электронных карт:" + 
                    Environment.NewLine + 
                    err.ToString()
                );
        }

        #endregion

        #region Read / Write Utils

        private const int BLOCKS_IN_SECTOR = 4;
        internal const int BLOCK_SIZE = 16;
        internal const int FIRST_USED_BLOCK = 4;        

        private static bool IsSystemBlock(int nBlock)
        {
            return
                nBlock == 0 ||
                (nBlock + 1) % BLOCKS_IN_SECTOR == 0;
        }

        internal static void IncrementBlock(ref int currentBlock)
        {
            do
            {
                currentBlock++;
            }
            while (IsSystemBlock(currentBlock));
        }

        #endregion

        #region Commands

        private CardReaderDeviceInfo ReadDeviceInfo()
        {
            byte[] response = ExecuteCommand(0x00, null);
            string deviceName = Encoding.GetEncoding(1251).GetString(response, 3, 20).TrimEnd('\0').Trim();
            return new CardReaderDeviceInfo() { DeviceName = deviceName };
        }

        public void SwitchSignalsStartCommand()
        {
            SwitchSignals(CardReaderSignals.GreenBeeper | CardReaderSignals.BeeperOne);
        }

        public void SwitchSignalsEndCommand()
        {
            SwitchSignals(CardReaderSignals.GreenBeeper | CardReaderSignals.BeeperOne);
        }

        private void SwitchSignals(CardReaderSignals signal)
        {
            byte[] response = ExecuteCommand(0x21, new byte[] { (byte)signal });
            ValidateAck(response);
        }

        public void InitializeCard()
        {
            ResetCard();
            SelectCard();
        }

        private void ResetCard()
        {
            ValidateAck(ExecuteCommand(0x22, null));
        }

        private void SelectCard()
        {
            ExecuteCommand(0x45, new byte[] { 0 });
        }

        public void AuthorizeBlockOnce(byte nBlock)
        {
            if (nBlock % BLOCKS_IN_SECTOR == 0)
                AuthorizeBlock(nBlock);
        }

        public void AuthorizeBlock(byte nBlock)
        {
            if (_password.Length != 6)
                throw new ArgumentException("g_Password.Length != 6");
            byte[] cmdData = new byte[8];
            cmdData[0] = 0x02; // ключ содержится в команде
            cmdData[1] = nBlock;
            _password.CopyTo(cmdData, 2);
            ExecuteCommand(0x50, cmdData);
        }

        public byte[] ReadBlock(byte nBlock)
        {
            if (IsSystemBlock(nBlock))
                throw new InvalidOperationException("Попытка чтения из системного блока сектора. Адрес блока: " + nBlock.ToString());
            byte[] response = ExecuteCommand(0x51, new byte[] { nBlock });
            byte[] result = new byte[BLOCK_SIZE];
            Array.Copy(response, 3, result, 0, BLOCK_SIZE);
            return result;
        }

        public void WriteBlock(byte nBlock, byte[] data)
        {
            if (IsSystemBlock(nBlock))
                throw new InvalidOperationException("Попытка записи в системный блок сектора. Адрес блока: " + nBlock.ToString());
            if (data.Length != BLOCK_SIZE)
                throw new ArgumentException("data.Length != BLOCK_SIZE");
            byte[] cmdData = new byte[BLOCK_SIZE + 1];
            cmdData[0] = nBlock;
            data.CopyTo(cmdData, 1);
            byte[] response = ExecuteCommand(0x52, cmdData);
            ValidateAck(response);
        }

        #endregion

        #region Command Management

        private byte[] ExecuteCommand(byte cmd, byte[] data)
        {
            WriteRequest(cmd, data);
            byte[] response = ReadResponse();
            ValidateFrameID(response);
            ValidateNack(response);
            return response;
        }

        private void ValidateFrameID(byte[] response)
        {
            if (response[1] != _frameIDGenerator.CurrentValue)
                throw new FormatException("response[1] != _FrameID");
        }

        private void ValidateNack(byte[] response)
        {
            if (response[2] == REPLY_ACK_NACK)
            {
                byte result = response[3];
                if (result != REPLY_ACK)
                    throw new FormatException("Error NACK" + result.ToString());
            }
        }

        private void ValidateAck(byte[] response)
        {
            if (response[2] != REPLY_ACK_NACK)
                throw new FormatException("Response type must be REPLY_ACK_NACK");
        }

        #endregion

        #region Transport

        #region Write Request

        private void WriteRequest(byte cmd, byte[] data)
        {
            byte[] req = GetRequest(cmd, data);
            _port.Write(req, 0, req.Length);
        }        

        private byte[] GetRequest(byte command, byte[] data)
        {
            MemoryStream msDest = new MemoryStream();

            msDest.WriteByte(FRAME_START); // стартовое условие            
            msDest.WriteByte(_frameIDGenerator.GetNextValue()); // идентификатор кадра
            msDest.WriteByte(command); // код комманды
            if (data != null)
                msDest.Write(data, 0, data.Length);
            msDest.WriteByte(0x00); // FCS, 2 байта
            msDest.WriteByte(0x00); // 
            msDest.WriteByte(FRAME_STOP); // стоповое условие

            byte[] result = msDest.ToArray();

            BitConverter.GetBytes(GetFCS(result)).CopyTo(result, result.Length - 3);

            return _byteStaffing.Encode(result);
        }

        #endregion

        #region Read Response

        private byte ReadByteFromPort()
        {
            return (byte)_port.ReadByte();
        }

        private byte[] ReadResponse()
        {
            while (ReadByteFromPort() != FRAME_START)
            { }

            MemoryStream msDest = new MemoryStream();

            msDest.WriteByte(FRAME_START);
            byte receivedByte;
            do
            {
                receivedByte = ReadByteFromPort();
                msDest.WriteByte(receivedByte);
            }
            while (receivedByte != FRAME_STOP);

            byte[] receivedBytes = _byteStaffing.Decode(msDest.ToArray());

            if (GetFCS(receivedBytes) != BitConverter.ToUInt16(receivedBytes, receivedBytes.Length - 3))
                throw new FormatException("FCS error");

            return receivedBytes;
        }

        #endregion

        private UInt16 GetFCS(byte[] data)
        {
            UInt32 fcs = 0xFFFF;
            for (int i = 1; i < data.Length - 3; i++)
            {
                UInt32 cb = data[i];
                UInt32 w = (cb ^ fcs) & 0xFF;
                for (int j = 0; j < 8; j++)
                {
                    if ((w & 1) != 0)
                    {
                        w >>= 1;
                        w ^= 0x8408;
                    }
                    else
                        w >>= 1;
                }
                fcs = w ^ (fcs >> 8);
            }
            fcs ^= 0xFFFFFFFF;
            return (UInt16)fcs;
        }

        #endregion

        #region Device Constants

        private const byte FRAME_START = 0xFD;
        private const byte FRAME_STOP = 0xFE;
        private const byte FRAME_STAFFED_BYTE = 0xFF;

        private const byte STAFFED_FRAME_STAFFED_BYTE = 0x00;
        private const byte STAFFED_FRAME_START = 0x02;
        private const byte STAFFED_FRAME_STOP = 0x01;

        private const byte REPLY_ACK_NACK = 0x2A;
        private const byte REPLY_ACK = 0x55;

        [Flags]
        private enum CardReaderSignals : byte
        {
            AllOff = 0x00,
            GreenOff = 0x00,
            GreenOn = 0x01,
            GreenBlink = 0x02,
            GreenBeeper = 0x03,
            RedOff = 0x00,
            RedOn = 0x04,
            RedBlink = 0x08,
            RedBeeper = 0x0C,
            BeeperOff = 0x00,
            BeeperOne = 0x10,
            BeeperDouble = 0x20,
            BeeperLong = 0x30,
            Default = 0x80
        }

        #endregion
    }

    public class CardReaderDeviceInfo
    {
        public string DeviceName { get; set; }
    }

Смотри, начиная с метода ExecuteCommand.
...
Рейтинг: 0 / 0
потоки в C#
    #38675520
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КЕсть решение проще.
...
Это ничего не меняет.
железобетонно!
...
Рейтинг: 0 / 0
потоки в C#
    #38675531
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикАлексей КЕсть решение проще.
...
Это ничего не меняет.
железобетонно!Два, на мой взгляд, наиболее правильных решения изложил выше, два раза. Уговаривать не собираюсь.
...
Рейтинг: 0 / 0
потоки в C#
    #38675651
Фотография fortibransa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roer Из строкового названия перечисления, получить само перечисление, например:
Код: c#
1.
serialPort.Parity = (System.IO.Ports.Parity)typeof(System.IO.Ports.Parity).GetField(stringParityType).GetValue(typeof(System.IO.Ports.Parity));
...
Рейтинг: 0 / 0
потоки в C#
    #38675666
Фотография fortibransa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По основному вопросу.
Я читаю по 1 байту (вообще сколько придет), но DataRessive срабатывает уже на одном байте(serialPort.ReceivedBytesThreshold = 1 по умолчанию) и если
Есть Старт байт(ы) и Стоп байт(ы) соответственно обрабатываю, те собираю пока не получу Стоп байт(байты). Это описано в протоколе обмена для конкретного устройства.
При этом работает таймер для таймаута.

Если известно только кол-во байт, то:
также собираю пока не придет нужное кол-во байт.
При этом работает таймер для таймаута.
или
поменять serialPort.ReceivedBytesThreshold = на нужное кол-во байт.
...
Рейтинг: 0 / 0
потоки в C#
    #38675745
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
видимо топикстартеру приходит что-то такое 16077419
Код: c#
1.
>-00.002


начало посылки он однозначно определить сможет, а вот окончание, видимо только по длине, либо по началу следующей посылки
...
Рейтинг: 0 / 0
потоки в C#
    #38675795
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчиквидимо топикстартеру приходит что-то такое 16077419
Код: c#
1.
>-00.002


начало посылки он однозначно определить сможет, а вот окончание, видимо только по длине, либо по началу следующей посылкиЛибо по переводу строки, как это обычно принято в текстовых протоколах. Тогда достаточно связать StreamReader с компортом и сделать тупо ReadLine().
...
Рейтинг: 0 / 0
потоки в C#
    #38675797
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
зы: StreamReader не нужен, в компорте есть встроенный ReadLine().
...
Рейтинг: 0 / 0
потоки в C#
    #38675800
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
зы: Не забыть установить правильный SerialPort.Encoding
...
Рейтинг: 0 / 0
потоки в C#
    #38676839
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчик , а как твоим классом воспользоваться?
...
Рейтинг: 0 / 0
потоки в C#
    #38676851
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в общем так вроде работает. сейчас с сервисом проверю


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
///----
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;

namespace MyComReader
{
    public partial class Form1 : Form
    {
        MyComReader three = new MyComReader();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        #region mycom
        internal class MyComReader
        {
            private SerialPort port;
            private System.Timers.Timer timer;
            private System.Threading.Thread thread;
            readonly EventWaitHandle wh = new AutoResetEvent(false);
            private bool doWork;
            int i = 0;
            string value = "";
            private string inData = "";

            public void ThreadStart()
            {
                doWork = true;
                thread = new Thread(Execute);
                thread.Start();
              

                this.timer = new System.Timers.Timer();
                this.timer.Enabled = true;
                this.timer.Interval = 5000;
                this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
                this.timer.AutoReset = true;
                this.timer.Start();
            }

            public void ThreadStop()
            {
                doWork = false;
                timer.Stop();
                wh.Set();
            }

            void Execute()
            {

                while (doWork)
                {
                    if (port == null)
                    {
                        port = new SerialPort("COM2", 9600);
                        port.DataReceived += port_DataReceived;
                    }
                    if (!port.IsOpen)
                        port.Open();

                    port.Write("#10\r");
                    wh.WaitOne();
                  
                }
                if (port.IsOpen)
                    port.Close();
            }

            void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                wh.Set();
            }
            
            
            void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                
                SerialPort sp = (SerialPort)sender;

                inData += sp.ReadExisting();
               // MessageBox.Show(i++.ToString() +  inData);
                value = inData;
                if (value.Length > 10 && value.Contains('\r'))
                {
                    MessageBox.Show(value + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss\t"));
                    inData = "";
                }

                // проверка, если в InData появилась полная строка - отрезаем кусок
                // и обрабатываем, а лучше в другой поток для обработки передаем

            }

           
        }
        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            
            three.ThreadStart();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            three.ThreadStop();
        }
    }
}



...
Рейтинг: 0 / 0
потоки в C#
    #38676881
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
c cервисом тоже работает
...
Рейтинг: 0 / 0
25 сообщений из 76, страница 2 из 4
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / потоки в C#
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]