Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TCP/IP,在异步调用中初始化全局变量_C#_.net_Global Variables_Tcp - Fatal编程技术网

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

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

我有一个小小的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;
}

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

我想象这里发生的情况是,您有同时处理数据的并发调用,因此会产生结果

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

第二种方法是封装对静态变量的访问(顺便说一句,您没有完全清楚哪些变量受到影响),在这种封装中,同步访问(使用锁/监视器或其他机制)

然后,在上面的代码中使用局部变量,从局部静态变量复制值,执行您的工作,然后重新分配它们

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


第二种是当你有一个最后的wins方法时。

是的,我是线程新手:)让我问你一个初学者问题,首先变量不是静态的,它们只是在类中定义的,而不是在函数中本地定义的。如果我想要顺序访问,并且我按照第一个建议去做,并且在我想要更改的变量周围放置锁,那么如果第一个线程更改值并退出锁,然后第二个线程在第一个线程完成发送消息并将amessage和MessageLength设置为0之前更改它会怎么样。我试着在整个函数上加上一个锁,但是没有用。谢谢你的帮助。@Eitan:好吧,你不能把它放在整个函数中,你应该把它放在正在调用的异步方法中,以及你正在访问调用异步方法的代码中的方法的代码块中。
string newMessage = cleanMessage.Substring(MessageLength);
MessageLength = GetMessageLength(newMessage);
amessage = StripNumber(newMessage);