【问题标题】:Counter does not set back to zero C# [closed]计数器不设置回零 C# [关闭]
【发布时间】:2013-06-19 22:42:18
【问题描述】:

我创建了一个单例类,当我在启动 Visual Studio 后第一次执行它时,它会打印预期的结果,因为 count 的值最初为零,当它达到一个时它会退出循环但是,当我第二次执行它时,计数器值仍然保持为 1,即使在我停止调试后它也不会归零。请帮助我找到问题的解决方案。谢谢。 我的班级代码如下:

public partial class Singleton_class : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        CEO c1 = CEO.GetCeoObject("Rahul", "MS", 28);
        CEO c2 = CEO.GetCeoObject("Ram", "MS", 26);
        Response.Write(c1.name + " " + c1.qualifiaction + " " + c1.age + "<br/>");
        Response.Write(c2.name + " " + c2.qualifiaction + " " + c2.age + "<br/>");
     }
}
namespace Singleton
{
    public class CEO
    {
        public static CEO c1;
        public static int count;
        public string name;
        public string qualifiaction;
        public int age;

        private CEO(string n, string q, int a)
        {
            this.name = n;
            this.qualifiaction = q;
            this.age = a;
        }
        public static CEO GetCeoObject(string name, string quali, int age)
        {
            if (count == 0) //this remains at one
            {
                c1 = new CEO(name, quali, age);
                count++;
            }
            return c1;
        }
    }
}

【问题讨论】:

  • 静态变量在所有请求之间共享,并在应用程序域中发挥作用。如果系统重新启动您的 asp.net 应用程序,静态变量将丢失。
  • 不是线程安全的,不是单例的方式。 csharpindepth.com/articles/general/singleton.aspx
  • 如果你增加count++,你的代码看起来真的很奇怪,那么你为什么要检查它是否==0,快速浏览一下它可能只会工作一次
  • @DJKRAZE 感谢您的回复。我这样做是因为我只想打印第一个对象的值,无论用户创建了多少对象。
  • 您已经创建了一个类,该类在每次调用 GetCeoObject 方法时都静态返回相同的对象。除了实现上的弱点之外,这是一个 Singleton 类。现在,如果您想在每次调用该方法时获取不同的对象,则返回一个新对象并删除计数逻辑+

标签: c# asp.net counter


【解决方案1】:

IIS 不会在每次附加调试器时重新启动 AppPool,如果要重置计数器,则必须重新构建解决方案或触摸 web.config 文件以强制 IIS 重新启动 AppPool(您的静态变量是一直保留到 AppPool 回收为止)。

单例模式是一种确保在整个应用程序中只有一个对象实例的方法,因此在类上有一个私有构造函数并确保实例化实例的调用是线程安全的很重要。

以下是如何在 C# 中实现单例的两个示例:

public class Singleton
{
    private static readonly Singleton SingleInstance;

    static Singleton()
    {
        /* initializes the static field the first time anything is accessed on 
           the Singleton class .NET ensures threadsafety on static initializers. */
        SingleInstance = new Singleton(Datetime.Now);
    }

    public static Singleton Instance
    {
        get
        {
            return SingleInstance;
        }
    }
    /// <summary>
    /// Keep the constructure private on Singleton objects to avoid other instances being contructed
    /// </summary>
    private Singleton(DateTime value)
    {
        Value = value;
    }

    public DateTime Value { get; private set; }
}

如果您使用的是 .NET 4 或更高版本,您还可以使用 Lazy 来进一步简化单例

public class Singleton
{
    private static readonly Lazy<Singleton> LazyInstance = new Lazy<Singleton>(() => new Singleton(DateTime.Now));

    public static Singleton Instance
    {
        get
        {
            return LazyInstance.Value;
        }
    }
    /// <summary>
    /// Keep the constructure private on Singleton objects to avoid other instances being contructed
    /// </summary>
    private Singleton(DateTime value)
    {
        Value = value;
    }

    public DateTime Value { get; private set; }
}

【讨论】:

  • 感谢您的回答。 :) +1
【解决方案2】:

GetCeoObject 在第一次调用时创建内部静态对象c1
当您第二次调用它时,GetCeoObject 返回第一次调用中创建的 c1
您将其分配给不同的变量,但这与分配给第一个变量的 c1 实例的引用相同。它是对同一内存区域的引用。
当您打印这些值时,它会打印相同的值也就不足为奇了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-16
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多