之前我曾经问过这个话题,并且认为我已经掌握了它,但我发现我在这里遗漏了一些东西。我在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()); }
}
答案 0 :(得分:2)
您的异步代码正在触发异步,这是预期的......但这意味着处理顺序可能与接收顺序不同。例如:
.NET receive message 1
.NET receive message 2
.NET finish receive message 2
.NET finish receive message 1
在这里你假设你会看到1,然后是2,因为这是他们收到的订单,但不是他们收到的订单。
如果您的数据顺序很重要,您必须在大批量(坏)中一次性发送所有数据,或者按顺序接收它(底层TCP应确保以适当的顺序传递消息)。 / p>