C# TCP/IP,在异步调用中初始化全局变量
我有一个小小的tcp/ip程序,我一辈子都无法解决这个问题(我查过谷歌)。当我在BeginReceive的回调委托中读取缓冲区时,我将一些全局变量设置为0,但当函数启动时,变量中有数据。我在班上有两个全局变量:C# TCP/IP,在异步调用中初始化全局变量,c#,.net,global-variables,tcp,C#,.net,Global Variables,Tcp,我有一个小小的tcp/ip程序,我一辈子都无法解决这个问题(我查过谷歌)。当我在BeginReceive的回调委托中读取缓冲区时,我将一些全局变量设置为0,但当函数启动时,变量中有数据。我在班上有两个全局变量: string content; var buffer = ((byte[]) ar.AsyncState); int len = MySocket.EndReceive(ar); if (len > 0) { string cleanMessage; content
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
{
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;
}
GetMessageLength(newMessage)
返回一个0,而StripNumber(newMessage)
返回一个空字符串,但是下次调用函数时,在处理任何内容之前的函数开头,MessageLength=30,并且消息中有以前的数据。程序中没有其他地方引用这些变量,也就是说,我没有访问上述函数之外的变量,而且这两个变量都是全局变量。我想象这里发生的情况是,您有同时处理数据的并发调用,因此会产生结果
有两种解决方案。第一种方法是在上面代码中涉及静态(而非“全局”)变量的部分周围放置锁
第二种方法是封装对静态变量的访问(顺便说一句,您没有完全清楚哪些变量受到影响),在这种封装中,同步访问(使用锁/监视器或其他机制)
然后,在上面的代码中使用局部变量,从局部静态变量复制值,执行您的工作,然后重新分配它们
当您必须确保上面的代码连续运行时,您将使用第一种解决方案,换句话说,您必须确保读取、修改和写入都按顺序进行
第二种是当你有一个最后的wins方法时。是的,我是线程新手:)让我问你一个初学者问题,首先变量不是静态的,它们只是在类中定义的,而不是在函数中本地定义的。如果我想要顺序访问,并且我按照第一个建议去做,并且在我想要更改的变量周围放置锁,那么如果第一个线程更改值并退出锁,然后第二个线程在第一个线程完成发送消息并将amessage和MessageLength设置为0之前更改它会怎么样。我试着在整个函数上加上一个锁,但是没有用。谢谢你的帮助。@Eitan:好吧,你不能把它放在整个函数中,你应该把它放在正在调用的异步方法中,以及你正在访问调用异步方法的代码中的方法的代码块中。
string newMessage = cleanMessage.Substring(MessageLength);
MessageLength = GetMessageLength(newMessage);
amessage = StripNumber(newMessage);