【求助】C#中的集合如何做到线程同步? 现在我有一个这样的需求,在一个集合中。同时有多个现成访问集合的元素,在访问的同时,还可能会对集合进行排序。而这种情况下,可能在遇到正在排序的过程中枚举成员,造成存在的集合元素没有被找出来。请问,这样的情况有没有解决方案? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 加锁啊,特别对于排序时,只允许一个线程访问,排序完后,解锁,其他线程才可进入,最简单的 lock 因为我的排序是异步进行的。所以排序也有可能是多个线程。 现在造成的情况是,在排序之前获取了枚举器,然后排序,然后枚举这样就会找不到元素了。我贴下我的代码吧,希望高手能够给与指点。在下感谢了: public class XmlConfigSortedList<T> : List<T>, IEnumerable<T> where T : IMatchedContainer { /// <summary> /// 获取当前集合中项的总被匹配次数。 /// </summary> public long MatchCount { get; private set; } /// <summary> /// 当集合中存在一个匹配的配置节点。则事件会被触发 /// </summary> protected event MatchCompletedDelegate<T> MatchCompleted; /// <summary> /// 构造方法 /// </summary> public XmlConfigSortedList() { this.MatchCompleted += CurrentItemStatusChanged; this.MatchCompleted += Sort; } void Sort(object sender, T e) { const int n = 5; //每N次匹配成功,就进行一次排序。 //if (this.MatchCount % n == 0) { //QueueWorkForSort(this); AsynchronizeSort(this); } } void CurrentItemStatusChanged(object sender, T e) { e.MatchSuccess(); this.MatchCount++; } /// <summary> /// 指示当前集合成功匹配了指定项。并同时维护集合状态。也同时指示当前集合针对参数T成功匹配过一次。该方法一定会抛出 /// </summary> /// <param name="matchItem">已被匹配的对象</param> public void MatchedFor(T matchItem) { MatchCompleted(this, matchItem); } public new IEnumerator<T> GetEnumerator() { lock (this) { //var arr = new T[this.Count]; //CopyTo(arr); //return arr.AsEnumerable().GetEnumerator(); return base.GetEnumerator(); } } /// <summary> /// 异步对指定对象进行排序。 /// </summary> /// <param name="lst">要进行排序的对象</param> private void AsynchronizeSort(XmlConfigSortedList<T> lst) { int availableThreads; int completedThreads; ThreadPool.GetAvailableThreads(out availableThreads, out completedThreads); if (availableThreads > 0) { ThreadPool.QueueUserWorkItem(QueueWorkForSort, lst); } } private void QueueWorkForSort(object data) { lock (this) { XmlConfigSortedList<T> list = data as XmlConfigSortedList<T>; if (list != null) { list.Sort(new Comparison<T>((i1, i2) => i2.MatchCount.CompareTo(i1.MatchCount))); } } } } /// <summary> /// 指示指定的集合对象已完成排序。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public delegate void MatchCompletedDelegate<in T>(object sender, T e) where T : IMatchedContainer; ASP.NET网站程序,如何编写ActiveX插件加密客户登陆密码? 问个小问题,项目执行出来为什么是目录清单?不是网站呢。 练习VB.net写ASP,菜鸟求助 关于remoting配置问题 求助大虾 请教GridView的删除问题 url重写后路径错误的问题,兼散分 急,请大家帮帮忙。如何做弹出查找并取得返回值的窗口 那位大哥大组能给我一个Remoting 的例子 b/s模式的,我非常感激!!! gridview的串行问题 关于login控件 gridview的用法
where T : IMatchedContainer
{
/// <summary>
/// 获取当前集合中项的总被匹配次数。
/// </summary>
public long MatchCount { get; private set; } /// <summary>
/// 当集合中存在一个匹配的配置节点。则事件会被触发
/// </summary>
protected event MatchCompletedDelegate<T> MatchCompleted; /// <summary>
/// 构造方法
/// </summary>
public XmlConfigSortedList()
{
this.MatchCompleted += CurrentItemStatusChanged;
this.MatchCompleted += Sort;
} void Sort(object sender, T e)
{
const int n = 5;
//每N次匹配成功,就进行一次排序。
//if (this.MatchCount % n == 0)
{
//QueueWorkForSort(this);
AsynchronizeSort(this);
}
} void CurrentItemStatusChanged(object sender, T e)
{
e.MatchSuccess();
this.MatchCount++;
} /// <summary>
/// 指示当前集合成功匹配了指定项。并同时维护集合状态。也同时指示当前集合针对参数T成功匹配过一次。该方法一定会抛出
/// </summary>
/// <param name="matchItem">已被匹配的对象</param>
public void MatchedFor(T matchItem)
{
MatchCompleted(this, matchItem);
} public new IEnumerator<T> GetEnumerator()
{
lock (this)
{
//var arr = new T[this.Count];
//CopyTo(arr);
//return arr.AsEnumerable().GetEnumerator();
return base.GetEnumerator();
}
} /// <summary>
/// 异步对指定对象进行排序。
/// </summary>
/// <param name="lst">要进行排序的对象</param>
private void AsynchronizeSort(XmlConfigSortedList<T> lst)
{
int availableThreads;
int completedThreads;
ThreadPool.GetAvailableThreads(out availableThreads, out completedThreads); if (availableThreads > 0)
{
ThreadPool.QueueUserWorkItem(QueueWorkForSort, lst);
}
} private void QueueWorkForSort(object data)
{
lock (this)
{
XmlConfigSortedList<T> list = data as XmlConfigSortedList<T>;
if (list != null)
{
list.Sort(new Comparison<T>((i1, i2) => i2.MatchCount.CompareTo(i1.MatchCount))); }
} }
} /// <summary>
/// 指示指定的集合对象已完成排序。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void MatchCompletedDelegate<in T>(object sender, T e) where T : IMatchedContainer;