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被重置了-还有很多其他的格式化和逻辑。我对代码进行了大量简化,使其只关注我遇到的问题。我想在未来我会添加更多的评论来强调这一点…虽然很好地发现了。理解,并有点期待。我只是补充了一下,作为一个机会,它没有被重置。每隔一段时间,这种低垂的果实实际上就会奏效。