TCP / IP,在异步调用中初始化的全局变量

时间:2011-01-12 13:02:48

标签: 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 = 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;
}

在我所拥有的功能的最后:

string newMessage = cleanMessage.Substring(MessageLength);
MessageLength = GetMessageLength(newMessage);
amessage = StripNumber(newMessage);

GetMessageLength(newMessage)返回0并且StripNumber(newMessage)返回一个空字符串,但是下次我调用该函数时,在函数开头处理任何内容之前,MessageLength = 30并且amessage包含来自之前。程序中没有其他地方可以引用这些变量,即我没有访问上述函数之外的变量,而且这两个变量都是全局变量。

1 个答案:

答案 0 :(得分:1)

我想这里发生的事情是你有同时处理数据的并发调用,因此结果。

这有两个解决方案。第一种方法是在上面代码中触及静态(非“全局”)变量的部分周围放置锁。

第二种方法是封装对静态变量的访问(你没有完全清楚哪些变量受到影响btw),并且在封装中,同步访问(使用lock / Monitor或其他一些机制)。

然后,在上面的代码中使用局部变量,在本地复制静态变量中的值,执行工作,然后将它们分配回来。

当您必须确保上面的代码以串行方式运行时,您将使用第一个解决方案,换句话说,您必须确保读取,修改和写入都按顺序进行。

第二种方法是在你有最后一次胜利的时候。