Member 7754814 Ответов: 2

Как получить событие в последовательности


Привет,
Я столкнулся с проблемой при потреблении данных в событии в оконном приложении. Полученные данные не находятся в той же последовательности, что и отправленные из класса, где возникает событие. Вот полный сценарий.

Есть 2 потока. В одном потоке я постоянно получаю пакеты данных по TCP и помещаю их в массив. В другом потоке я выбираю эти данные из массива, затем обрабатываю их и отправляю на передний конец. Я поднимаю событие для отправки данных на передний конец.
Полученный пакет содержит числовой порядковый номер. При возникновении события отправляется один и тот же порядковый номер, но в переднем конце полученные номера не находятся в одной и той же последовательности.

Вот полный код. Я заменил код, связанный с сокетом.

namespace MyConnectionManager
{
    public delegate void DataReceivedHandler(int seqNum);

    public class MyConnection
    {
        public event DataReceivedHandler DataReceived;

        private Thread receiver = null;
        private Thread processor = null;
        private delegate void RecieveDelegate(int seqNum);
        private bool isSocketConnected = false;
        public MyConnection()
        {
        }

        public bool StartServer()
        {
            bool isStarted = false;
            try
            {
                receiver = new Thread(new ThreadStart(EnqueData));
                processor = new Thread(new ThreadStart(ProcessData));

                isSocketConnected = true;

                receiver.Start();
                processor.Start();

                isStarted = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return isStarted;
        }

        public bool StopServer()
        {
            bool isStopped = false;
            try
            {
                isSocketConnected = false;

                receiver = null;
                processor = null;

                isStopped = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return isStopped;
        }

        int dummyData = 1;
        private void EnqueData()
        {
            try
            {
                while (dummyData <= 100000)
                {
                    MyEnque(dummyData);
                    dummyData++; 
                }
            }
            catch (Exception ex) 
            { 
                Console.WriteLine("Exception :=> " + ex.Message); 
            }
        }

        private void ProcessData()
        {
            try
            {
                RecieveDelegatercvrdy = new RecieveDelegate(ReceiveReady);
                while (isSocketConnected)
                {
                    int recvd = MyDequeue();
                    if (recvd > 0)
                    {
                        rcvrdy.BeginInvoke(recvd, null, null);
                    }
                }
            }
            catch (Exception ex) 
            { 
                Console.WriteLine("Exception :=> " + ex.Message); 
            }
        }

        private void ReceiveReady(int seqNum)
        {
            try
            {
                if (DataReceived != null)
                    DataReceived(seqNum);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region Circular Array
        private int[] seqQueue = new int[1000000];
        private int readSeq = 0;
        private int writerSeq = 0;
        private int restart = 0;

        private void MyEnque(int Data)
        {
            try
            {
                if (writerSeq >= 999999)
                {
                    writerSeq = 0;
                    restart  = 1;
                }

                seqQueue[writerSeq] = Data;
                writerSeq++;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private int MyDequeue()
        {
            int myOutput = null;
            try
            {
                if (readSeq < writerSeq && lPacketQueue[readSeq] != null)
                {
                    myOutput = seqQueue[readSeq];
                    readSeq++;
                }

                if (readSeq > writerSeq && lRestartArray == 1)
                {
                    if (readSeq >= 999999)
                    {
                        readSeq = 0;
                        restart = 0;
                    }

                    if (lPacketQueue[readSeq] != null)
                    {
                        myOutput = seqQueue[readSeq];
                        readSeq++;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return myOutput;
        }
        #endregion
    }
}

namespace MyMain
{
    class Program
    {
        static MyConnection conn = new MyConnection();

        static void Main(string[] args)
        {
            try
            {
                conn.DataReceived += conn_DataReceived;
                System.Threading.Thread.Sleep(5000);

                conn.StartServer();
                Console.WriteLine("Waiting to finish....");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception :=> " + ex.Message);
            }
        }

        static void conn_DataReceived(int seqNum)
        {
            try
            {
                Console.WriteLine("Received Seq Num :=> {0}", seqNum);

                if(seqNum >= 100000)
                    conn.StopServer();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception :=> " + ex.Message);
            }
        }
    }
}


ВЫХОД
Received Seq Num :=> 1
Received Seq Num :=> 2
Received Seq Num :=> 4
Received Seq Num :=> 6
Received Seq Num :=> 3
Received Seq Num :=> 7
Received Seq Num :=> 5
.....
Received Seq Num :=> 100000
Received Seq Num :=> 99956
Received Seq Num :=> 99999
Received Seq Num :=> 99998


Может ли кто-нибудь помочь мне получить эти данные в той же последовательности, что и отправленные сервером внутри события?

Спасибо и с уважением,

Что я уже пробовал:

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

2 Ответов

Рейтинг:
2

Leo Chapiro

Если вы отправляете и получаете данные асинхронно, нет никакой гарантии получить эти данные в той же последовательности, что и отправленные.


Рейтинг:
0

BillW33

Как сказал _duDE_, если вы отправляете пакеты данных асинхронно, нет никакого способа узнать порядок, в котором они будут получены. То, что вы должны сделать на принимающей стороне, - это собрать пакеты в правильном порядке. Для этого они должны быть отправлены с некоторым полем, которое указывает правильный порядок. Это означает, что принимающая сторона может ждать пакета 1 после того, как уже получила пакеты 2 и 3. Как только у вас есть раздел данных в правильном порядке, вы можете отправить этот раздел на любую обработку, которую вам нужно сделать.