0

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

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

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

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

5 回答 5

4

此代码的线程“不安全”可能是问题所在,因为当您的线程当前处于同一方法的中间时,其他线程可能会调用 Send(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
    }
}
于 2009-07-17T12:30:54.997 回答
2

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

Message.Send("");

或者您的 AppDomain 正在卸载。没有更多信息,很难确定。

于 2009-07-17T12:26:41.050 回答
2

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

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

这现在作为静态的,但是是per-thread。避免了危机;但这有点……好吧,我自己会尽量避免这种需要——但它会很好用。

重要:初始化器是每个线程,而不是每个请求;由于您的线程很可能会被重新使用,因此您应该确保在尝试使用它之前初始化状态,否则您可能会遇到旧垃圾。

于 2009-07-17T12:44:16.717 回答
0

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

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

于 2009-07-17T12:28:45.013 回答
0

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

编写调用 Message.Send("Hello World"); 的单元测试或简单测试工具。并对输出进行断言。将其与您的调用代码库隔离开来,可以了解是您的 Message 类行为异常,还是消费者发送了错误/意外数据。

此外,除非您的 //rest of function 包括重置您的 bool,否则在发送第一条消息后它将始终为 true。

于 2009-07-17T12:58:12.510 回答