Created
August 19, 2010 11:05
-
-
Save karno/537613 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
// *!* があるところが心配なところ。 | |
namespace Azrael.Kernel.Base | |
{ | |
/// <summary> | |
/// ストレージのベース実装 | |
/// </summary> | |
public class SafeList<T> : IList<T>, ILockOperatable | |
{ | |
/// <summary> | |
/// データ保持リスト | |
/// </summary> | |
private List<T> internalList; | |
/// <summary> | |
/// internalStorageのロックオブジェクト | |
/// </summary> | |
private object iLocker; | |
public SafeList() | |
{ | |
internalList = new List<T>(); | |
iLocker = new object(); | |
} | |
/// <summary> | |
/// 保持しているアイテムの個数 | |
/// </summary> | |
public int Count | |
{ | |
// *!* | |
// Countプロパティはマルチスレッドでアクセスしても問題ない はず。 | |
// 内部的にプロパティ持ってるんじゃないかな? | |
get { return internalList.Count; } | |
} | |
public T this[int index] | |
{ | |
get { return internalList[index]; } | |
set { internalList[index] = value; } | |
} | |
/// <summary> | |
/// アイテムを追加します。 | |
/// </summary> | |
/// <param name="item">追加アイテム</param> | |
public void Add(T item) | |
{ | |
lock (iLocker) | |
{ | |
internalList.Add(item); | |
} | |
} | |
/// <summary> | |
/// アイテム コレクションを追加します。<para /> | |
/// 多重列挙に対応したコレクションを指定する必要があります。 | |
/// </summary> | |
/// <param name="item">追加アイテム コレクション</param> | |
public void Add(IEnumerable<T> item) | |
{ | |
lock (iLocker) | |
{ | |
internalList.AddRange(item); | |
} | |
} | |
/// <summary> | |
/// アイテム コレクションを追加します。<para /> | |
/// 一度だけ列挙動作を行います。 | |
/// </summary> | |
/// <remarks> | |
/// 列挙操作中は内部ストレージがロックされるので、 | |
/// コストの大きい操作は登録しないようにしてください。 | |
/// </remarks> | |
/// <param name="item">アイテムの列挙</param> | |
public void AddOnce(IEnumerable<T> item) | |
{ | |
lock (iLocker) | |
{ | |
foreach (var i in item) | |
AddUnsafe(i); | |
} | |
} | |
/// <summary> | |
/// ストレージをロックせずにアイテムを追加します。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はAddメソッドを使用してください。 | |
/// </summary> | |
public void AddUnsafe(T item) | |
{ | |
internalList.Add(item); | |
} | |
/// <summary> | |
/// ストレージをロックせずにアイテムの列挙を追加します。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はAddメソッドを使用してください。 | |
/// </summary> | |
public void AddUnsafe(IEnumerable<T> item) | |
{ | |
internalList.AddRange(item); | |
} | |
/// <summary> | |
/// アイテム コレクションを追加します。<para /> | |
/// 一度だけ列挙動作を行います。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はAddOnceメソッドを使用してください。 | |
/// </summary> | |
/// <remarks> | |
/// 列挙操作中は内部ストレージがロックされるので、 | |
/// コストの大きい操作は登録しないようにしてください。 | |
/// </remarks> | |
/// <param name="item">アイテムの列挙</param> | |
public void AddOnceUnsafe(IEnumerable<T> item) | |
{ | |
foreach (var i in item) | |
AddUnsafe(i); | |
} | |
/// <summary> | |
/// すべての要素を削除します。 | |
/// </summary> | |
public void Clear() | |
{ | |
lock (iLocker) | |
{ | |
internalList.Clear(); | |
} | |
} | |
/// <summary> | |
/// 指定したアイテムを取り除きます。 | |
/// </summary> | |
public bool Remove(T item) | |
{ | |
lock (iLocker) | |
{ | |
return internalList.Remove(item); | |
} | |
} | |
/// <summary> | |
/// 指定したインデックスに存在するアイテムを取り除きます。 | |
/// </summary> | |
public void RemoveAt(int index) | |
{ | |
lock (iLocker) | |
{ | |
if (internalList.Count <= index) | |
throw new ArgumentOutOfRangeException("index"); | |
internalList.RemoveAt(index); | |
} | |
} | |
/// <summary> | |
/// 指定した述語条件に一致するすべての要素を取り除きます。 | |
/// </summary> | |
public void RemoveAll(Predicate<T> match) | |
{ | |
lock (iLocker) | |
{ | |
internalList.RemoveAll(match); | |
} | |
} | |
/// <summary> | |
/// すべての要素を削除します。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はClearメソッドを使用してください。 | |
/// </summary> | |
public void ClearUnsafe() | |
{ | |
internalList.Clear(); | |
} | |
/// <summary> | |
/// 指定したアイテムを取り除きます。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はRemoveメソッドを使用してください。 | |
/// </summary> | |
public bool RemoveUnsafe(T item) | |
{ | |
return internalList.Remove(item); | |
} | |
/// <summary> | |
/// 指定したインデックスに存在するアイテムを取り除きます。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はRemoveAtメソッドを使用してください。 | |
/// </summary> | |
public void RemoveAtUnsafe(int index) | |
{ | |
if (internalList.Count <= index) | |
throw new ArgumentOutOfRangeException("index"); | |
internalList.RemoveAt(index); | |
} | |
/// <summary> | |
/// 指定した述語条件に一致するすべての要素を取り除きます。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はRemoveAllメソッドを使用してください。 | |
/// </summary> | |
public void RemoveAllUnsafe(Predicate<T> match) | |
{ | |
internalList.RemoveAll(match); | |
} | |
/// <summary> | |
/// 要素を配列化します。 | |
/// </summary> | |
public T[] ToArray() | |
{ | |
lock (iLocker) | |
{ | |
return internalList.ToArray(); | |
} | |
} | |
/// <summary> | |
/// 要素を配列化します。<para /> | |
/// マルチスレッド操作に対してロックされません。通常はToArrayメソッドを使用してください。 | |
/// </summary> | |
public T[] ToArrayUnsafe() | |
{ | |
return internalList.ToArray(); | |
} | |
#region IEnumerable メンバー | |
/// <summary> | |
/// 格納しているアイテムを取得します。 | |
/// </summary> | |
public IEnumerable<T> Items | |
{ | |
get { return internalList; } | |
} | |
public IEnumerator<T> GetEnumerator() | |
{ | |
return internalList.GetEnumerator(); | |
} | |
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
#endregion | |
#region ILockOperatable メンバー | |
public void LockOperate(Delegate operation, object arguments) | |
{ | |
lock (iLocker) | |
{ | |
operation.DynamicInvoke(arguments); | |
} | |
} | |
public TResult LockOperate<TResult>(Delegate operation, object arguments) | |
{ | |
lock (iLocker) | |
{ | |
return (TResult)operation.DynamicInvoke(arguments); | |
} | |
} | |
#endregion | |
#region IList<T> メンバー | |
public int IndexOf(T item) | |
{ | |
lock (iLocker) | |
{ | |
return internalList.IndexOf(item); | |
} | |
} | |
public void Insert(int index, T item) | |
{ | |
lock (iLocker) | |
{ | |
internalList.Insert(index, item); | |
} | |
} | |
public void InsertUnsafe(int index, T item) | |
{ | |
internalList.Insert(index, item); | |
} | |
#endregion | |
#region ICollection<T> メンバー | |
public bool Contains(T item) | |
{ | |
// *!* | |
return internalList.Contains(item); | |
} | |
public void CopyTo(T[] array, int arrayIndex) | |
{ | |
lock (iLocker) | |
{ | |
internalList.CopyTo(array, arrayIndex); | |
} | |
} | |
/// <summary> | |
/// 常に更新可能です。 | |
/// </summary> | |
public bool IsReadOnly | |
{ | |
get { return false; } | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment