2

我之前曾询问过这个话题,并认为我已经掌握了它,但我发现我在这里遗漏了一些东西。我在 linux 中有一些 C 代码,我通过套接字将数据发送到我的 C# winforms 可视化代码。我正在尽可能快地从 C 发送数据,这非常快。但在 C# 中,我的 datagridview 没有正确更新。如果我放慢将数据发送到 c# 代码的速度,它就可以了。但我真的不能那样做。我真的要死在这里了。

所以在 C# 中,这就是我所拥有的:

{
   . . .
sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sListener.Bind(new IPEndPoint(0, 1994));
Listen();
}
private void Listen()
    {
        sListener.Listen(10);

        // Begins an asynchronous operation to accept an attempt 
        AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
        sListener.BeginAccept(aCallback, sListener);
    }

    public void AcceptCallback(IAsyncResult ar)
    {
        Socket listener = null;

        // A new Socket to handle remote host communication 
        Socket handler = null;
        try
        {
            // Receiving byte array 
            byte[] buffer = new byte[1024];
            // Get Listening Socket object 
            listener = (Socket)ar.AsyncState;
            // Create a new socket 
            handler = listener.EndAccept(ar);

            // Using the Nagle algorithm 
            handler.NoDelay = false;

            // Creates one object array for passing data 
            object[] obj = new object[2];
            obj[0] = buffer;
            obj[1] = handler;

            // Begins to asynchronously receive data 
            handler.BeginReceive( buffer, 0, buffer.Length, SocketFlags.None,  new AsyncCallback(ReceiveCallback), obj);

            // Begins an asynchronous operation to accept an attempt 
            AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
            listener.BeginAccept(aCallback, listener);
        }
        catch (Exception exc) { MessageBox.Show(exc.ToString()); }
    }

    public void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Fetch a user-defined object that contains information 
            object[] obj = new object[2];
            obj = (object[])ar.AsyncState;

            // Received byte array 
            byte[] buffer = (byte[])obj[0];

            // A Socket to handle remote host communication. 
            handler = (Socket)obj[1];

            // Received message 
            string content = string.Empty;

            // The number of bytes received. 
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                Array.Resize(ref buffer, bytesRead);
                double[] values = new double[buffer.Length / 8];
                int i = 0;
                values[i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);

                this.Invoke((MethodInvoker)delegate()
                {
                    if (dataGridView1.Rows.Count > 5)
                    {
                        dataGridView1.Rows.RemoveAt(this.dataGridView1.Rows[5].Index);
                    }
                    dataGridView1.Rows[0].Cells[1].Value = values[0];
                    dataGridView1.Rows[1].Cells[1].Value = values[1];
                    dataGridView1.Rows[2].Cells[1].Value = values[2];
                    dataGridView1.Rows[3].Cells[1].Value = values[3];
                    dataGridView1.Rows[4].Cells[1].Value = values[4];

                });
            }
            // Continues to asynchronously receive data
            byte[] buffernew = new byte[1024];
            obj[0] = buffernew;
            obj[1] = handler;
            handler.BeginReceive(buffernew, 0, buffernew.Length,
            SocketFlags.None,
            new AsyncCallback(ReceiveCallback), obj);                   
        }
        catch (Exception exc) { MessageBox.Show(exc.ToString()); }
    }
4

1 回答 1

2

您的异步代码正在触发异步,这是预期的......但这意味着处理顺序可能与接收顺序不同。例如:

.NET receive message 1
.NET receive message 2
.NET finish receive message 2
.NET finish receive message 1

在这里,您假设您会看到 1,然后是 2,因为这是接收它们的顺序,而不是它们完成接收的顺序。

如果您的数据顺序很重要,您必须要么一次大批量发送所有数据(不好),要么按顺序接收(底层 TCP 应确保以适当的顺序传递消息)。

于 2013-06-06T02:43:24.043 回答