I have this small tcp/ip program and for the life of me I can't figure this problem out (I checked google). When I am reading a buffer in the callback delegate of BeginReceive I set some global variables to 0 but when the function starts there is data in the variables. I have two global variables in the class:
string content;
var buffer = ((byte[]) ar.AsyncState);
int len = MySocket.EndReceive(ar);
if (len > 0)
{
string cleanMessage;
content = Encoding.ASCII.GetString(buffer, 0, len);
if (MessageLength == 0)
{
MessageLength = GetMessageLength(content);
cleanMessage = StripNumber(content);
}
else
cleanMessage = content;
if(cleanMessage.Length <1)
{
if(MySocket.Connected)
MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
new AsyncCallback(Read), buffer);
return;
}
if(MessageLength > cleanMessage.Length)
{
MessageLength = MessageLength - cleanMessage.Length;
amessage += cleanMessage;
}
else
{
开发者_C百科 amessage += cleanMessage.Substring(0, MessageLength);
if (OnRead != null)
{
var e = new CommandEventArgs(this, amessage);
Control target = null;
if (OnRead.Target is Control)
target = (Control)OnRead.Target;
if (target != null && target.InvokeRequired)
target.Invoke(OnRead, this, e);
else
OnRead(this, e);
}
string newMessage = cleanMessage.Substring(MessageLength);
MessageLength = GetMessageLength(newMessage);
amessage = StripNumber(newMessage);
}
MySocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
new AsyncCallback(Read), buffer);
return;
}
In the end of the function where I have:
string newMessage = cleanMessage.Substring(MessageLength);
MessageLength = GetMessageLength(newMessage);
amessage = StripNumber(newMessage);
GetMessageLength(newMessage)
returns a 0 and StripNumber(newMessage)
returns an empty string, but the next time I call the function, at the beginning of the function before anything is processed, MessageLength = 30 and amessage has data from before. No other place in the program to a reference these variables i.e. I'm not accessing the variables outside the function above and both variables are global.
I imagine what is happening here is that you have concurrent calls that are working on the data at the same time, hence the results.
There are two solutions to this. The first would be to place locks around the section that touches your static (not "global") variables in the code above.
The second would be to encapsulate access to the static variables (you aren't making it perfectly clear which variables are being impacted btw) and in that encapsulation, synchronize access (using lock/Monitor or some other mechanism).
Then, use local variables in the code above, copying the values from the static variables locally, performing your work, and then assigning them back.
You would use the first solution when you have to be sure that the code above runs serially, in other words, you have to make sure that the read, the modification, and the write all occur in order.
The second would be for when you have a last-in-wins approach.
精彩评论