C# 静态成员不保留指定的值

C# 静态成员不保留指定的值,c#,static-members,C#,Static Members,好的,我有一个静态类,它有两个静态成员,一个字符串和一个布尔值。 公共静态方法根据传入参数的状态为这些成员分配值 然后调用一个私有静态方法来处理静态成员 问题是,虽然布尔值保持它在公共函数中设置的值,但字符串没有;它默认返回其初始值。这是为什么? 简化代码如下 static class MessageHandler { private static String m_messageToSend = String.Empty; private static bool m_requi

好的,我有一个静态类,它有两个静态成员,一个字符串和一个布尔值。
公共静态方法根据传入参数的状态为这些成员分配值

然后调用一个私有静态方法来处理静态成员

问题是,虽然布尔值保持它在公共函数中设置的值,但字符串没有;它默认返回其初始值。这是为什么?
简化代码如下

static class MessageHandler
{
    private static String m_messageToSend = String.Empty;
    private static bool m_requiresACK = false;


    public static void Send(String message)
    {
         //formatting etc (actual method sets more fields)
         m_messageToSend = message;
         m_requiresACK = true;

         Send();
    }

    private void static Send()
    {
        SendMessageDelegate sendDelegate = DoSend;
        //At this point m_requiresACK remains true but m_messageToSend does not 
        //hold value of message; it is empty.
        IAsyncResult ar = sendDelegate.BeginInvoke(m_messageToSend, m_requiresACK);


        //rest of function
    }
}

//some other class
MessageHandler.Send("Hello");

这很可能是由于另一个线程调用

Message.Send("");

或者正在卸载您的AppDomain。如果没有更多的信息,很难说清楚。

如果一个字段保持相同的值,而另一个字段没有,我会非常惊讶

如果这是一个Web应用程序,如果应用程序被回收,就会发生这种情况。

< P>该代码的线程“不安全”可能是问题所在,因为其他线程可以调用String(String),而您的线程当前处于同一方法的中间。我建议对Message类进行以下重写:

static class Message
{
    public static void Send(String message)
    {
         Send(message, true);
    }

    private void static Send(string messageToSend, bool requiresACK)
    {
        SendMessageDelegate sendDelegate = DoSend;
        IAsyncResult ar = sendDelegate.BeginInvoke(messageToSend, requiresACK);

        //rest of function
    }
}

你有一些巨大的线程安全问题。如果你真的想要这个静态,有一个大胆的修正:

[ThreadStatic]
private static String m_messageToSend = String.Empty;
[ThreadStatic]
private static bool m_requiresACK = false;
这现在起到静态作用,但每个线程都是。避免了危机;但这有点。。。嗯,我会尽量避免这种需要,我自己-但它会很好地工作


重要提示:初始值设定项是每个线程,而不是每个请求;由于您的线程可能会被重复使用,因此您应该确保在尝试使用它之前初始化状态,否则您可能会有旧的垃圾。

我在您的注释中看到,在第一行之后,私有变量是空的,而不是保存参数的值。当您点击Send()的第一行时,这是真的吗

编写一个单元测试或一个调用Message.Send(“helloworld”)的简单测试工具;并对输出执行断言。将其与调用代码库隔离可能有助于了解是您的消息类行为异常,还是消费者发送了错误/意外的数据


此外,除非//函数的其余部分包括重置bool,否则在发送第一条消息后,bool将始终为true。

您确定Send(string)方法正确分配了bool。在简化tge代码时,您是否忘记提及任何内容?为什么这是一个静态类?Devio-也许不应该,我还在学习。这似乎是最优雅的解决方案,不需要创建对象。类名不是很好,可能需要更改-MessageHandler,因为它在上转发它们。MessageHandler.Send(Message.Peter)-这似乎已经解决了问题。碰巧的是,我直接使用了成员,因为我最近倾向于使用成员,而不是传递大量的参数(实际上不止列出)。当然,在这个例子中,传递参数似乎更有意义,比如课程的马。成员变量通常是可以的,但是静态成员变量在涉及线程安全时需要特别注意。很高兴它解决了这个问题。一次只能调用一个线程,但是谢谢提示!我确实有一个初始化方法,但删除了它以减少代码。碰巧是的,bool被重置了-还有很多其他的格式化和逻辑。我对代码进行了大量简化,使其只关注我遇到的问题。我想在未来我会添加更多的评论来强调这一点…虽然很好地发现了。理解,并有点期待。我只是补充了一下,作为一个机会,它没有被重置。每隔一段时间,这种低垂的果实实际上就会奏效。