麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

編寫高質量代碼改善C#程序的157個建議[泛型集合、選擇集合、集合的安全]

2019-11-17 03:14:25
字體:
來源:轉載
供稿:網友

編寫高質量代碼改善C#程序的157個建議[泛型集合、選擇集合、集合的安全]

前言

  軟件開發過程中,不可避免會用到集合,C#中的集合表現為數組和若干集合類。不管是數組還是集合類,它們都有各自的優缺點。如何使用好集合是我們在開發過程中必須掌握的技巧。不要小看這些技巧,一旦在開發中使用了錯誤的集合或針對集合的方法,應用程序將會背離你的預想而運行。

  本文已更新至http://www.companysz.com/aehyok/p/3624579.html。本文主要學習記錄以下內容:

  建議20、使用泛型集合來替代非泛型集合

  建議21、選擇正確的集合

  建議22、確保集合的線性安全

建議20、使用泛型集合來替代非泛型集合

http://www.companysz.com/aehyok/p/3384637.html這里有一篇文章,是我之前專門來介紹泛型的。我們應盡量的使用泛型集合。因為泛型的確有它的好處:

1、提供了類型安全,在編譯期間就可以檢查錯誤

2、更重要的是大部分情況下泛型集合的性能比非泛型集合的性能都高很多。

下面我們來看一段簡單的測試性能的代碼:

class PRogram    {        static int collectionCount = 0;        static Stopwatch watch = null;        static int testCount = 10000000;        static void TestBegin()        {            GC.Collect(); ////強制對所有代碼進行即時垃圾回收            GC.WaitForPendingFinalizers();////掛起線程,執行終結器隊列中的終結器(即析構方法)            GC.Collect();///再次對所有代碼進行垃圾回收,主要包括從終結器隊列中出來的對象            collectionCount = GC.CollectionCount(0);///返回在0代中執行的垃圾回收次數            watch = new Stopwatch();            watch.Start();        }        static void TestEnd()        {            watch.Stop();            Console.WriteLine("耗時:{0}",watch.ElapsedMilliseconds.ToString());            Console.WriteLine("垃圾回收次數:{0}", GC.CollectionCount(0) - collectionCount);        }        static void TestArrayList()        {            ArrayList arrayList = new ArrayList();            int temp = 0;            for (int i = 0; i < testCount; i++)            {                arrayList.Add(i);                temp = (int)arrayList[i];            }            arrayList = null;        }        static void TestGenericList()        {            List<int> list = new List<int>();            int temp = 0;            for (int i = 0; i < testCount; i++)            {                list.Add(i);                temp = list[i];            }            list = null;        }        static void Main(string[] args)        {            Console.WriteLine("開始測試ArrayList");            TestBegin();            TestArrayList();            TestEnd();            Console.WriteLine("開始測試List<T>");            TestBegin();            TestGenericList();            TestEnd();            Console.ReadLine();        }    }

執行結果如下

  我上面測試的次數是10000000,可以發現,兩者在垃圾回收次數和耗時都差距比較大,所以泛型集合有著非泛型集合無法超越的優勢。所以還是盡量在我們的程序中使用泛型集合吧。

建議21、選擇正確的集合

http://www.companysz.com/aehyok/p/3643928.html這里有一篇我剛寫的關于集合的博文,主要是簡單介紹了一下關于自己使用比較頻繁的幾個集合。

如果集合的數目固定并且不涉及轉型,使用數組效率高,否則就是使用List<T>。

像使用數組、ArrayList、List<T>、Dictionary<key,value>這些集合的有點就是插入和刪除數據效率比較高,缺點就是查找的效率相對來說低一些。

關于隊列可以參考http://msdn.microsoft.com/zh-cn/library/System.Collections.Queue(v=vs.80).aspx

關于棧可以參考http://msdn.microsoft.com/zh-cn/library/System.Collections.Stack(v=vs.110).aspx

建議22、確保集合的線性安全

  建議18中提到,foreach循環不能代替for循環的一個原因是在迭代過程中對集合本身進行了增刪操作。將此場景移植到多線程場景中,就是本建議要闡述的重點:確保集合的線程安全。集合線程安全是指在多個線程上添加活刪除元素時,線程之間必須保持同步。

  下面我們來通過實例來更詳細的查看一下,先簡單定義一個實體類

    public class Person    {        public string Name { get; set; }        public int Age { get; set; }    }
       static List<Person> list = new List<Person>()         {             new Person(){ Name="aehyok",Age=25},            new Person(){Name="Kris",Age=23},            new Person(){Name="Leo",Age=26}        };        static AutoResetEvent autoSet = new AutoResetEvent(false);        static void Main(string[] args)        {            Thread t1 = new Thread(() =>             {                ///阻止當前線程                autoSet.WaitOne();                   foreach (var item in list)                {                    Console.WriteLine("t1:"+item.Name);                    Thread.Sleep(1000);                }            });            t1.Start();            Thread t2 = new Thread(() =>             {                 ///通知t1可以執行代碼                autoSet.Set();                Thread.Sleep(1000);                list.RemoveAt(2);            });            t2.Start();            Console.ReadLine();        }

再來簡單分析一下這段代碼,其實就是閑定義了一個List集合,然后又定義了一個 AutoRestEvent的實例,用于控制線程的。

接下來在Main函數中定義了兩個線程,在線程一中將線程一暫停,然后當調用線程二的時候再來通知線程一繼續運行。最終運行結果

主要是因為線程一在暫停之后,開始運行線程二隨即線程一得到通知可以繼續運行,通過代碼可以發現都有Thread.Sleep(1000);也就是為了保證兩個線程都還在運行期間,線程二移除了集合中的一個元素,那么當線程一再次循環的時候,導致了錯誤的發生。

早在泛型集合出現之前,非泛型集合一般會提供一個SyncRoot屬性,要保證非泛型集合的線程安全,可以通過鎖定該屬性來實現。如果上面的集合用ArrayList代替,保證線程安全則應該在迭代和刪除的時候都加上鎖lock,代碼如下所示:

        static ArrayList list = new ArrayList()         {             new Person(){ Name="aehyok",Age=25},            new Person(){Name="Kris",Age=23},            new Person(){Name="Leo",Age=26}        };        static AutoResetEvent autoSet = new AutoResetEvent(false);        static void Main(string[] args)        {            Thread t1 = new Thread(() =>             {                ///阻止當前線程                autoSet.WaitOne();                lock (list.SyncRoot)                {                    foreach (Person item in list)                    {                        Console.WriteLine("t1:" + item.Name);                        Thread.Sleep(1000);                    }                }            });            t1.Start();            Thread t2 = new Thread(() =>             {                 ///通知t1可以執行代碼                autoSet.Set();                Thread.Sleep(1000);                lock (list.SyncRoot)                {                    list.RemoveAt(2);                }                            });            t2.Start();            Console.ReadLine();        }

運行結果就是線程一執行通過

如果你試過,那么會發現泛型集合沒有這樣的屬性來進行加鎖,必須要自己創建一個鎖定對象來完成同步的任務。

所以第一個例子我們可以這樣進行修改

 static List<Person> list = new List<Person>()         {             new Person(){ Name="aehyok",Age=25},            new Person(){Name="Kris",Age=23},            new Person(){Name="Leo",Age=26}        };        static object SyncObject = new object();        static AutoResetEvent autoSet = new AutoResetEvent(false);        static void Main(string[] args)        {            Thread t1 = new Thread(() =>             {                ///阻止當前線程                autoSet.WaitOne();                lock (SyncObject)                {                    foreach (var item in list)                    {                        Console.WriteLine("t1:" + item.Name);                        Thread.Sleep(1000);                    }                }            });            t1.Start();            Thread t2 = new Thread(() =>             {                 ///通知t1可以執行代碼                autoSet.Set();                Thread.Sleep(1000);                lock (SyncObject)                {                    list.RemoveAt(2);                }             });            t2.Start();            Console.ReadLine();        }

英語小貼士

blind date——相親

online session——在線會議

This depends on you ——這取決于你

I have a date with you——我和你有個約會

poor guy——可憐的家伙,也可以說成(a poor fish)

You look so tall——你看上去很高(形容人高不要用high)

Awesome——令人敬畏的;使人畏懼的;可怕的;極好的

Awesome——聽某某說也可以翻譯成(So.Diao)

作者:aehyok

出處:http://www.companysz.com/aehyok/

感謝您的閱讀,如果您對我的博客所講述的內容有興趣,那不妨點個推薦吧,謝謝支持:-O。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产一区二区三区视频免费 | 亚洲无马在线观看 | 在线中文字幕观看 | 91精选视频| 91午夜免费视频 | 久久久久久久一区 | 成人 精品| 亚洲成人伊人 | 久久综合久久综合久久综合 | 在线中文字幕播放 | 国产一区二区三区手机在线 | 国产日韩a| 99这里精品 | 国产午夜精品一区二区三区免费 | 欧美熟videos肥婆 | 国产一级毛片在线看 | 日韩三区视频 | 亚洲最大久久 | 爱逼爱操综合网 | 中文字幕一区二区三区四区 | 外国一级黄色片 | 北京一级毛片 | 蜜桃av网 | 成人国产精品久久久 | 久久草在线视频国产 | 精品99在线视频 | 欧美 日韩 三区 | 国产又白又嫩又紧又爽18p | 欧美一区二区三区免费观看 | 午夜视频色 | 操你啦免费视频 | 久久精品国产一区二区电影 | 欧美 亚洲 视频 | 久夜草| 日韩美香港a一级毛片免费 日韩激情 | 欧美成人精品一区 | 国产在线一级视频 | 亚洲第一综合色 | 少妇一级淫片免费放4p | 深夜福利视频免费观看 | 国产精品视频2021 |