C#读写锁定列表

时间:2013-11-17 05:00:10

标签: c# timer

Desription:    我每秒都会添加一些数据。每10秒后,数据将保存到数据库,然后清除列表。如果我停止计时器,我将保存列表中剩余的数据,然后清除列表,然后停止计时器。 在上面的代码中,假设我在11秒后停止计时器,Class1s列表应该只有1个数据,但我看到有11个数据。你们能告诉我这里做错了吗?也许我对锁的使用不正确或者我的代码完全不正确

public class Class1Singleton
{
    private static Class1Singleton Class1Singleton;
    private static List<Class1> Class1s;
    private static Timer saveClass1Timer;
    private static readonly object lock1 = new object();
    private Class1Singleton()
    {
    }

    public static Class1Singleton getInstance()
    {
        if (Class1Singleton == null) {
            try
            {
                Class1Singleton = new Class1Singleton();
            }
            catch (Exception e){}
        }
        return Class1Singleton;
    }

    public void StartTimer()
    {
        if (saveClass1Timer == null)
        {
            saveClass1Timer = new Timer(10000);
            //saveClass1Timer.Interval = 10000;
            saveClass1Timer.Elapsed += new ElapsedEventHandler(SaveClass1);
            saveClass1Timer.Enabled = true;
        }
    }

    public  void SaveClass1(object sender, ElapsedEventArgs e)
    {
        try {
            lock (lock1)
            {
                new Class1Repository().InsertAllClass1(Class1s);
                ClearWorkoutList();
            }
        }
        catch (Exception ex){}
    }

    public  void InsertClass1(List<Class1> Class1)
    {
        if (Class1s == null)
        {
            Class1s = new List<Class1>(Class1);
        }
        else
        {
            lock (lock1)
            {
                Class1s.AddRange(Class1);
            }
        }
    }

    public  void ClearWorkoutList()
    {
        if (Class1s != null)
        {
            Class1s.Clear();
        }
    }

    public  void StopTimer()
    {
        if (Class1s != null && Class1s.Count > 0)
        {
            lock (lock1)
            {
                new Class1Repository().InsertAllClass1(Class1s);
                ClearWorkoutList();
            }
        }
        if (saveClass1Timer != null && saveClass1Timer.Enabled == true)
        {
            saveClass1Timer.Stop();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我对您的代码进行了一些更改(请参阅注释):

public class Class1Singleton
{
    // This is the way Jon Skeet recommends implementing a singleton in C#
    // See http://csharpindepth.com/Articles/General/Singleton.aspx
    static readonly Class1Singleton instance = new Class1Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Class1Singleton() { }

    // There's only one instance of Class1Singleton so there's
    // no advantage in making the members static
    private List<Class1> Class1s;
    private Timer saveClass1Timer;
    private readonly object lock1 = new object();

    Class1Singleton()
    {
    }

    public static Class1Singleton Instance
    {
        get { return instance; }
    }

    public void StartTimer()
    {
        // If you're using this class in a multi-thread environment,
        // all methods that access the list or timer should be locked
        lock (lock1)
        {
            if (saveClass1Timer == null)
            {
                saveClass1Timer = new Timer(10000);
                //saveClass1Timer.Interval = 10000;
                saveClass1Timer.Elapsed += new ElapsedEventHandler(SaveClass1);
                saveClass1Timer.Enabled = true;
            }
        }
    }

    // SaveClass1 doesn't need to be public
    private void SaveClass1(object sender, ElapsedEventArgs e)
    {
        lock (lock1)
        {
            SaveWorkoutList();
            ClearWorkoutList();
        }            
    }

    private void SaveWorkoutList()
    {
        //new Class1Repository().InsertAllClass1(Class1s);
    }

    public void InsertClass1(List<Class1> Class1)
    {
        lock (lock1)
        {
            if (Class1s == null)
                Class1s = new List<Class1>(Class1);
            else
                Class1s.AddRange(Class1);
        }
    }

    private void ClearWorkoutList()
    {
        if (Class1s != null)
        {
            Class1s.Clear();
        }
    }

    public void StopTimer()
    {
        lock (lock1)
        {
            if (Class1s != null && Class1s.Count > 0)
            {
                SaveWorkoutList();
                ClearWorkoutList();
            }

            if (saveClass1Timer != null && saveClass1Timer.Enabled == true)
            {
                saveClass1Timer.Stop();
            }
        }
    }

}