C# 变量神秘变化的值

C# 变量神秘变化的值,c#,.net,multithreading,tcp,C#,.net,Multithreading,Tcp,编辑:好的,我有一个字符串连接函数的问题,与线程无关,但知道它不会是线程的问题,请引导我找到答案谢谢你的回答 我正在制作一个简单的tcp/ip聊天程序,用于练习线程和tcp/ip。我使用的是异步方法,但并发性有问题,所以我选择了线程和阻塞方法(不是异步的)。我在类中定义了两个私有变量,不是静态的: string amessage = string.Empty; int MessageLength; 和一根线 private Thread BeginRead; 好的,当客户端启动时,我调用一个

编辑:好的,我有一个字符串连接函数的问题,与线程无关,但知道它不会是线程的问题,请引导我找到答案谢谢你的回答

我正在制作一个简单的tcp/ip聊天程序,用于练习线程和tcp/ip。我使用的是异步方法,但并发性有问题,所以我选择了线程和阻塞方法(不是异步的)。我在类中定义了两个私有变量,不是静态的:

string amessage = string.Empty;
int MessageLength;
和一根线

private Thread BeginRead;
好的,当客户端启动时,我调用一个名为Listen的函数:

public virtual void Listen(int byteLength)
        {
            var state = new StateObject {Buffer = new byte[byteLength]};
            BeginRead = new Thread(ReadThread);
            BeginRead.Start(state);                
        }
最后是接收和处理命令的函数,我将缩短它,因为它非常长:

  private void ReadThread(object objectState)
    {
       var state = (StateObject)objectState;
       int byteLength = state.Buffer.Length;
       while (true)
          {

              var buffer = new byte[byteLength];
              int len = MySocket.Receive(buffer);
              if (len <= 0) return;               
              string content = Encoding.ASCII.GetString(buffer, 0, len);
              amessage += cleanMessage.Substring(0, MessageLength);
              if (OnRead != null)
                {
                   var e = new CommandEventArgs(amessage);
                   OnRead(this, e);
                 }

           }

    }
在服务器中:

private void Accept(IAsyncResult result)
        {

                var client = new AbstractClient(MySocket.EndAccept(result));
                var e = new CommandEventArgs(client, null);
                    Clients.Add(client);
                    client.Listen(5);
                    if (OnClientAdded != null)
                    {
                        var target = (Control) OnClientAdded.Target;
                        if (target != null && target.InvokeRequired)
                            target.Invoke(OnClientAdded, this, e);
                        else
                            OnClientAdded(this, e);


                    }


                    client.OnRead += OnRead;
                    MySocket.BeginAccept(new AsyncCallback(Accept), null);

        }

所有这些代码都在一个名为AbstractClient的类中。客户端继承抽象客户端,当服务器接受套接字时,它创建自己的本地抽象客户端,在本例中,两个模块都访问上述函数,但它们是不同的实例,我无法想象来自不同实例的线程会组合在一起,尤其是因为没有静态变量。

我假设OnRead正在触发线程池线程上调度的事件。如果任何已注册的事件处理程序正在写入
amessage
,则其值可能会在您处于读取循环中的任何时候发生更改


仍然不太清楚在循环中从何处获取分配给
amessage
的值。应该
cleanmessage
read
content

我假设OnRead正在触发线程池线程上调度的事件。如果任何已注册的事件处理程序正在写入
amessage
,则其值可能会在您处于读取循环中的任何时候发生更改


仍然不太清楚在循环中从何处获取分配给
amessage
的值。如果
cleanmessage
阅读
content

那么,你描述它的方式就没有意义了。这可能意味着你认为正在发生的事情并不是真正正在发生的事情。调试线程化代码相当困难,很难在程序发生错误时捕捉到程序的状态

一种通用的方法是在代码中添加日志记录。在代码中加入Debug.WriteLine()语句,这些语句显示变量的当前值以及线程的ManagedId。您可能会获得大量的输出,但在某些地方您会看到输出出错。或者,您可以充分了解线程是如何交互的,从而猜测问题的根源


仅仅添加日志本身就可以解决这个问题,因为它改变了代码的计时。发生这种情况很糟糕。

好吧,这和你描述的方式毫无意义。这可能意味着你认为正在发生的事情并不是真正正在发生的事情。调试线程化代码相当困难,很难在程序发生错误时捕捉到程序的状态

一种通用的方法是在代码中添加日志记录。在代码中加入Debug.WriteLine()语句,这些语句显示变量的当前值以及线程的ManagedId。您可能会获得大量的输出,但在某些地方您会看到输出出错。或者,您可以充分了解线程是如何交互的,从而猜测问题的根源


仅仅添加日志本身就可以解决这个问题,因为它改变了代码的计时。发生这种情况时很糟糕。

你只调用它一次-你能显示调用
的任何代码吗?Listen
?什么是“cleanMessage”?OnRead做什么呢?我用cleanMessage去掉了分隔符之类的,我去掉了代码,因为它很长,实际上与线程无关。OnRead是一个在MessageEventArgs中包含整个消息的事件。我的缓冲区仅用于测试,因此通常不会在一次读取中发送整个消息。
aMessage
真的需要是类型成员吗?从代码上看,一个本地的就足够了。@Marc我编辑了这篇文章,加入了调用listen的代码。我从服务器和客户端都调用它。您只调用一次-您能显示调用
Listen
的任何代码吗?什么是“cleanMessage”?OnRead做什么呢?我用cleanMessage去掉了分隔符之类的,我去掉了代码,因为它很长,实际上与线程无关。OnRead是一个在MessageEventArgs中包含整个消息的事件。我的缓冲区仅用于测试,因此通常不会在一次读取中发送整个消息。
aMessage
真的需要是类型成员吗?从代码上看,一个本地的就足够了。@Marc我编辑了这篇文章,加入了调用listen的代码。我从服务器和客户端都调用它。这可能是一个愚蠢的问题,但我认为字符串是一种值类型,不像引用类型那样引用地址。编辑:很抱歉,它是一个引用类型,但不可变,所以我不明白它如何在OnRead事件中发生更改。。。我不是想暗示在CommandEventArgs对象中写入副本会更改消息,只是如果类型中有任何其他代码写入消息,则会由事件触发触发,这也许可以解释。这可能是一个愚蠢的问题,但我认为字符串是一种值类型,不像引用类型那样引用地址。编辑:很抱歉,它是一个引用类型,但不可变,所以我不明白它如何在OnRead事件中发生更改。。。我不是想暗示在CommandEventArgs对象中写入副本会更改消息,只是如果类型中有任何其他代码写入消息(由事件触发触发),这可能可以解释它。是的,我知道,如果我添加一个线程。睡眠一切正常。好吧,我会继续寻找:-)是的,我知道,如果我添加一个线程。睡眠一切工作。好吧,我会继续找的:-)
private void Accept(IAsyncResult result)
        {

                var client = new AbstractClient(MySocket.EndAccept(result));
                var e = new CommandEventArgs(client, null);
                    Clients.Add(client);
                    client.Listen(5);
                    if (OnClientAdded != null)
                    {
                        var target = (Control) OnClientAdded.Target;
                        if (target != null && target.InvokeRequired)
                            target.Invoke(OnClientAdded, this, e);
                        else
                            OnClientAdded(this, e);


                    }


                    client.OnRead += OnRead;
                    MySocket.BeginAccept(new AsyncCallback(Accept), null);

        }