1:確保集合的線程安全 html
若是使用.net4.0,有新的線程安全集合類
新的 System.Collections.Concurrent 命名空間引入了多個新的線程安全集合類,可在須要時隨時提供對項的無鎖訪問,並在鎖適用時提供細粒度鎖定。 在多線程方案中使用這些類應得到優於集合類型(例如, ArrayList 和 List <(Of <(T >)>))的性能。數據庫
除了System.Collections.Concurrent空間下集合外,非泛型集合使用
lock(非泛型集合對象.SyncRoot)進行鎖定達到集合線程安全目的
泛型集合使用
static object sycObj = new object(); //是否static看具體應用
lock (sycObj)
{
//操做集合。
}安全
2:循環中先求長度仍是使用list.Count,哪一個效率高多線程
第一類:閉包
int len = list.Count; 異步
for(int i; i<len; i++)ide
{性能
迭代this
}spa
第二類:
for(int i; i<list.Count; i++)
{
迭代
}
答案是同樣高。
第一種方法徹底沒有必要,不少人可能覺得那樣會爲代碼帶來效率,而其實是不會給效率帶來任何提高。
由於事實上,索引器內部,爲了安全期間,仍是會去求整個list的count的。將二者代碼貼出來可能會更好的理解這一點:
public T this[int index]
{
get
{
if (index >= this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException();
}
return this._items[index];
}
set
{
if (index >= this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException();
}
this._items[index] = value;
this._version++;
}
}
public int Count
{
get
{
return this._size;
}
}
3:善用延遲求值
以List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};爲例,說明linq查詢中的延遲求值和主動求值。
List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var temp1 = from c in list where c > 5 select c;
var temp2 = (from c in list where c > 5 select c).ToList<int>();
list[0] = 11;
Console.Write("temp1: ");
foreach (var item in temp1)
{
Console.Write(item.ToString() + " ");
}
Console.Write("\ntemp2: ");
foreach (var item in temp2)
{
Console.Write(item.ToString() + " ");
}
4:謹慎泛型類型中的靜態成員
static void Main(string[] args)
{
MyList<int> list1 = new MyList<int>();
MyList<int> list2 = new MyList<int>();
MyList<string> list3 = new MyList<string>();
Console.WriteLine(MyList<int>.Count);//2
Console.WriteLine(MyList<string>.Count);//1
}
class MyList<T>
{
public static int Count { get; set; }
public MyList()
{
Count++;
}
}
代碼輸出是莫子?
只要知道 MyList<int> 和 MyList<string> 是兩個不一樣的類型,這題就不難理解了。.NET 中類型參數不一樣的封閉泛型類型是不一樣的類型。
5:當心閉包中的陷阱
for (int i = 0; i < 10; i++)
{
Action t = () =>
{
Console.WriteLine("t1:" + i.ToString());
};
t.BeginInvoke(null, null);
}
以上代碼的輸出爲?
當閉包中引用了外部的局部變量或者方法參數的時候,C#會把該變量編譯成一個類的實例字段,頂樓的代碼編譯後實際上等效於:
TempClass tp = new TempClass();
for (tp.i = 0; tp.i < 10; tp.i++)
{
Action t = tp.TempMethod;
t.BeginInvoke(null, null);
}
TempClass是C#編譯器自動生成的類,其定義大概是這樣:
class TempClass
{
public int i;
public void TempMethod()
{
Console.Writeline("t1:" + i.ToString());
}
}
由於只循環10次,幾乎一瞬間就完了,所以第一個異步委託還沒開始執行 tp.i 就等於10了
6:event關鍵字的做用
既然使用委託也能實現回調,爲何又須要event關鍵字。答曰:event 最大的做用就是防止在類的外部觸發類的事件。
7:區分IEnumerable<T>和IQueryable<T>
本地數據源用IEnumerable<T>,遠程數據源用IQueryable<T>。
針對LinqLINQ TO to OBJECTS,使用Enumerable中的擴展方法對本地集合進行排序、查詢等操做,查詢參數接受的是Func< >。Func< >叫作謂語表達式,至關於一個委託。針對LinqLINQ TO to SQL則使用Querable中的擴展方法,它接受的參數是Expression< >。Expression< >用於包裝Func< >。LinqLINQ TO to SQL引擎最終會將表達式樹轉化成爲相應的SQL語句,而後在數據庫中執行。
8:選擇正確的集合
查看此文吧:http://www.cnblogs.com/luminji/archive/2011/03/24/1993393.html
9:泛型參數的約束是否是應該叫約定更好
在泛型的使用過程當中,經常使用到的一個功能就是爲泛型參數設定約束。約束聽上去像是限制了泛型參數的使用範圍,而實際上,約束自己確實拓展了泛型參數的使用。
一個沒有約束的泛型參數,只能具備object的行爲和屬性,而一個指定約束爲Student的泛型參數,卻可使用類型Student的全部公開屬性和方法。
因此,俺以爲約束這個詞翻譯的實在很差,叫約定多好。
10:減小使用自定義委託
FCL中的3個(或者說3系列)委託已經知足了大部分自定義委託的需求,因此基本上再也不須要自定義委託了。
它們是:
Action表示接受0個或多個輸入參數,執行一段代碼,可是沒有任何返回值;
Func表示接受0個或多個輸入參數,執行一段代碼,同時有返回值;
Predicate表示定義一組條件並判斷參數是否符合條件;
更多話題,期待下一期。