如何按顺序接收事件 [英] How to receive event in sequence

查看:66
本文介绍了如何按顺序接收事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在窗口应用程序中使用事件时遇到问题。收到的数据与从引发事件的类发送的顺序不同。这是完整的场景。



有2个主题。在一个线程中,我不断地通过TCP接收数据包并将其放入数组中。在其他线程中,我从数组中选择数据,然后处理该数据,然后将其发送到前端。我正在筹集事件以将数据发送到前端。

收到的数据包包含数字序列号。当事件被引发时,发送相同的序列号,但收到的前端号码不是相同的序列。



这是完整的代码。我已经替换了与Socket相关的代码。



 命名空间 MyConnectionManager 
{
public delegate void DataReceivedHandler( int seqNum);

public class MyConnection
{
public event DataReceivedHandler DataReceived;

private 线程接收器= null ;
private 线程处理器= null ;
private delegate void RecieveDelegate ( int seqNum);
private bool isSocketConnected = false ;
public MyConnection()
{
}

public bool StartServer()
{
bool isStarted = < span class =code-keyword> false ;
尝试
{
receiver = new 线程( new ThreadStart(EnqueData));
processor = new 线程( new ThreadStart(ProcessData));

isSocketConnected = true ;

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

isStarted = true ;
}
catch (例外情况)
{
throw ex;
}
return isStarted;
}

public bool StopServer()
{
bool isStopped = false ;
尝试
{
isSocketConnected = false ;

receiver = null ;
processor = null ;

isStopped = true ;
}
catch (例外情况)
{
throw ex;
}
返回 isStopped;
}

int dummyData = 1 ;
private void EnqueData()
{
尝试
{
while (dummyData < = 100000
{
MyEnque(dummyData);
dummyData ++;
}
}
catch (例外情况)
{
Console.WriteLine( 例外:=> + ex.Message);
}
}

私有 void ProcessData( )
{
try
{
RecieveDelegatercvrdy = new RecieveDelegate(ReceiveReady);
while (isSocketConnected)
{
int recvd = MyDequeue( );
如果(recvd > 0
{
rcvrdy.BeginInvoke(recvd, null null ) ;
}
}
}
catch (例外情况)
{
Console.WriteLine ( 例外:=> + ex.Message);
}
}

私人 void ReceiveReady( int seqNum)
{
尝试
{
if (DataReceived!= null
DataReceived(seqNum);
}
catch (例外情况)
{
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 数据)
{
尝试
{
if (writerSeq > = 999999
{
writerSeq = 0 ;
restart = 1 ;
}

seqQueue [writerSeq] =数据;
writerSeq ++;
}
catch (例外情况)
{
throw ex;
}
}

私人 int MyDequeue( )
{
int myOutput = null ;
尝试
{
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 (例外情况)
{
throw ex;
}
return myOutput;
}
#endregion
}
}

命名空间 MyMain
{
class 程序
{
static MyConnection conn = new MyConnection();

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

conn.StartServer();
Console.WriteLine( 等待完成....);
Console.ReadLine();
}
catch (例外情况)
{
Console.WriteLine( 例外:=> + ex.Message);
}
}

静态 void conn_DataReceived( int seqNum)
{
尝试
{
Console.WriteLine( 收到Seq Num:=> {0},seqNum);

if (seqNum > = 100000
conn.StopServer();
}
catch (例外情况)
{
Console.WriteLine( 例外:=> + ex.Message);
}
}
}
}





OUTPUT

收到Seq Num:=> 1 
收到Seq Num:=> 2
收到Seq Num:=> 4
收到Seq Num:=> 6
收到Seq Num:=> 3
收到Seq Num:=> 7
收到Seq Num:=> 5
.....
收到Seq Num:=> 100000
收到Seq Num:=> 99956
收到Seq Num:=> 99999
收到Seq Num:=> 99998





有人能帮助我按照服务器内部事件发送的相同顺序接收这些数据吗?



谢谢和问候,



我的尝试:



请检查我在相关主要部分添加的完整代码。

解决方案

如果异步发送和接收数据,则没有保证以与发送时相同的顺序获取此数据。


如_duDE_所述,如果异步发送数据包,则无法知道它们的接收顺序。您在接收端需要做的是将数据包重组为正确的顺序。为此,必须使用一些表示正确顺序的字段发送它们。这意味着接收端可能必须在已经获得数据包2和3之后等待数据包1.一旦您以正确的顺序获得了一部分数据,您就可以将该部分发送到您需要执行的任何处理。

Hi,
I am facing issue while consuming data in event in window application. Data received is not in same sequence as sent from class where event is raised. Here is complete scenario.

There are 2 threads. In one thread, I receive data packets over TCP continuously and put it in array. In other thread, I pick that data from array then process that data and then send it to front end. I am raising event to send data to front end.
Received packet contains numeric sequence number. When event is raised, same sequence number is sent but in front end numbers received are not in same sequence.

Here is complete code. I have replaced Socket related code.

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);
            }
        }
    }
}



OUTPUT

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



Can anybody help me in receiving this data in same sequence as sent by server inside event?

Thanks and Regards,

What I have tried:

Please check the complete code that I have added in main section in question.

解决方案

If you send and receive the data asynchronous, there is no guarantee to get this data in the same sequence as sent.


As _duDE_ said, if you send data packets asynchronously there is no way to know the order in which they will be received. What you have to do on the receiving end is to reassemble the packets into the correct order. To do this they must be sent with some field that indicates the correct order. This does mean that the receiving end may have to wait for packet 1 after already getting packets 2 and 3. Once you have a section of data in the correct order you can then send that section on to whatever processing you need to do.


这篇关于如何按顺序接收事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆