静态成员不保留指定的值

时间:2009-07-17 12:24:28

标签: c# static-members

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

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

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

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");

5 个答案:

答案 0 :(得分:4)

此代码的“不安全”线程可能是问题所在,因为当您的线程当前处于同一方法的中间时,其他线程可以调用Send(字符串)。我建议以下重写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
    }
}

答案 1 :(得分:2)

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

Message.Send("");

或正在卸载您的AppDomain。没有更多信息,很难肯定地说。

答案 2 :(得分:2)

那里有一些巨大的线程安全问题。如果你真的想要这个静态,那就是一个厚颜无耻的修复:

[ThreadStatic]
private static String m_messageToSend = String.Empty;
[ThreadStatic]
private static bool m_requiresACK = false;

这现在充当静态,但每线程。危机避免;但这有点......好吧,我会尽量避免这种需要,我自己 - 但它会正常工作。

重要:初始化程序是每个线程,而不是每个请求;因为你的线程很可能会被重用,你应该确保在尝试使用之前初始化状态,否则你可能会有旧的垃圾。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

我在你的评论中看到,在第一行之后,私有变量是空的而不是保存参数的值。一旦你点击Send()的第一行,这是真的吗?

编写单元测试或调用Message.Send(“Hello World”)的简单测试工具;并在输出上执行断言。将此与您的调用代码库隔离可以说明它是否是您的Message类行为异常,或者它是否是消费者发送错误/意外数据。

此外,除非您的其余功能包括重置您的bool,否则在发送第一条消息后它将始终为真。