zoukankan      html  css  js  c++  java
  • 公用类库积累

     

     

    俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力。

    本篇的公用类库的介绍主题是程序开发中多线程操作环境中,常用到的线程安全的各类同步集合、字典等对象,这些辅助类通过封装及继承关系,获得更加丰富完善的集合类,并且增加了线程锁,实现多线程访问的集合类。本篇随笔介绍包含有有序字典集合、同步字典集合、有序同步字典集合、同步列表、同步先进先出队列等对象。

    本篇继续继续整理优化已有的共用类库,并继续发表随笔介绍公用类库的接口方法以及详细使用操作,力求给自己继续优化,积攒更丰富的公用类库资源,加深了解的同时,也给大家展现公用类库好的方面。

    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(9)----各种常用辅助类
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(8)----非对称加密、BASE64加密、MD5等常用加密处理
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(7)-----声音播放、硬件信息、键盘模拟及钩子、鼠标模拟及钩子等设备相关 
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(6)----全屏截图、图标获取、图片打印、页面预览截屏、图片复杂操作等
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(5)----热键、多线程、窗体动画冻结等窗体操作
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(4)----CSV、Excel、INI文件、独立存储等文件相关
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(3)----数据库相关操作
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(2)----常用操作
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(1)----开篇总结

    1、有序的字典集合 OrderedDictionary。  

    实现效果

    1) 本辅助类主要是用来方便实现有序的字典集合操作。 一个有序的字典是一个集合类,它里面的项目可以通过其索引或他们的键进行操作。。 
    2) 有序集合对象,特点是查找非常高效率,并且提供了强类型的数据操作,不过由于其需要额外在列表中存储数据,因此尽量减少插入或者删除集合对象。 
    3) 有序的字典集合,虽然存在一些缺点,但是提供了一个非常灵活和用户友好数据结构,允许通过键值或索引进行访问。

    实现代码

    1)辅助类提供的方法接口如下所示: 

    /// <summary>    
    /// 判断字典<see cref="System.Collections.Generic.Dictionary{TKey, TValue}"></see> 是否包含指定的值。
    /// </summary>
    /// <param name="value">待判断的值,如果值为引用类型,则可以为null</param>
    /// <returns>
    /// 如果字典包含项目,则返回true,否则为false。
    /// </returns>
    public virtual bool ContainsValue(TValue value)

    /// <summary>
    /// 判断字典是否包含指定键的元素
    /// </summary>
    /// <param name="key">在字典中查找的键.</param>
    /// <returns>
    /// 如果字典中包含指定键的元素,返回true,否则为false
    /// </returns>
    /// <exception cref="System.ArgumentNullException">键为空</exception>
    public virtual bool ContainsKey(TKey key)

    /// <summary>
    /// 在字典中添加一个元素,根据提供的键和值
    /// </summary>
    /// <param name="key">作为待添加元素的键</param>
    /// <param name="value">作为待添加元素的值.</param>
    /// <exception cref="System.NotSupportedException">字典对象为只读</exception>
    /// <exception cref="System.ArgumentException">含有相同键的元素已经存在字典中</exception>
    /// <exception cref="System.ArgumentNullException">键为空.</exception>
    public virtual void Add(TKey key, TValue value)

    /// <summary>
    /// 在指定的索引插入元素
    /// </summary>
    /// <param name="index">插入位置,从零开始的索引</param>
    /// <param name="key">作为待插入元素的键</param>
    /// <param name="value">作为待插入元素的值</param>
    /// <exception cref="T:System.NotSupportedException">集合为只读</exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">指定索引在<see cref="T:System.Collections.Generic.IList`1"></see>中为无效索引.</exception>
    public void Insert(int index, TKey key, TValue value)

    /// <summary>
    /// 获取指定键的元素索引
    /// </summary>
    /// <param name="key">待查找的键</param>
    /// <returns>
    /// 如果列表中发现则为项目的索引,否则为-1。
    /// </returns>
    public int IndexOf(TKey key)

    /// <summary>
    /// 获取指定键的元素索引
    /// </summary>
    /// <param name="value">待查找的键</param>
    /// <returns>
    /// 如果列表中发现则为项目的索引,否则为-1。
    /// </returns>
    public int IndexOf(TValue value)

    /// <summary>
    /// 获取或设置与指定键的值。
    /// </summary>
    public virtual TValue this[TKey key]

    /// <summary>获取或设置指定索引相关联的值</summary>
    /// <returns>返回指定索引中关联的值, 如果指定的索引为无效,获取或设置操作将抛出 <see cref="ArgumentOutOfRangeException"></see>
    /// </returns>
    /// <param name="index">获取或设置值的索引</param>
    /// <exception cref="ArgumentOutOfRangeException">索引大于集合数量或者小于0</exception>
    public virtual TValue this[int index]

    /// <summary>
    /// 复制集合元素到数组中, 以数组的索引开始.
    /// </summary>
    /// <param name="array">一维数组<see cref="System.Array"></see>,它是从集合中复制的目标。数组对象必须是从零开始的索引。</param>
    /// <param name="arrayIndex">Array中的从零开始的索引,位于复制开始。</param>
    /// <exception cref="System.ArgumentOutOfRangeException">arrayIndex 小于0</exception>
    /// <exception cref="System.ArgumentNullException">array 为null</exception>
    /// <exception cref="System.ArgumentException">
    /// 数组为多维;或arrayIndex等于或大于数组的长度;
    /// 或源集合中元素的数量大于arrayIndex到目标数组结束间可用空间。
    /// 或者TKey的类型不能自动转换为目标数组的类型。</exception>
    public virtual void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)

    /// <summary>
    /// 创建一个新的对象,它是当前实例的一个副本
    /// </summary>
    /// <returns>
    /// 一个新的对象,此实例的一个副本。
    /// </returns>
    public OrderedDictionary<TKey, TValue> Clone()

    2)辅助类OrderedDictionary的使用例子代码如下所示,由于OrderedDictionary在检索的时候效率很高,而且可以通过索引和键进行定位,提供了较好的操作性和方便性。 输出结果如下所示,我们看到,他们虽然可以通过键和索引进行访问,但是他们的顺序不会发生变化。

    OrderedDictionary<string, string> syncDict = new OrderedDictionary<string, string>();    
    syncDict.Add("A", "testA");
    syncDict.Add("C", "testC");
    syncDict.Add("B", "TestB");

    //通过键访问
    StringBuilder sb = new StringBuilder();
    foreach (string key in syncDict.Keys)
    {
    sb.AppendFormat("{0}:{1}\r\n", key, syncDict[key]);
    }
    sb.AppendLine();

    //通过索引访问
    for (int i = 0; i < syncDict.Keys.Count; i++)
    {
    sb.AppendFormat("{0}:{1}\r\n", i, syncDict[i]);
    }
    MessageUtil.ShowTips(sb.ToString());

    3)  辅助类OrderedDictionary和.NET框架内置SortedDictionary不同,他虽然都支持泛型类型,不过键和索引方式访问,后者只是对键进行排序的字典类,并未提供以索引方式进行取值的。

    //框架内置的排序字典    
    SortedDictionary<string, string> sortDict = new SortedDictionary<string, string>();
    sortDict.Add("A", "testA");
    sortDict.Add("C", "testC");
    sortDict.Add("B", "TestB");

    sb = new StringBuilder();
    foreach (string key in sortDict.Keys)
    {
    sb.AppendFormat("{0}:{1}\r\n", key, sortDict[key]);
    }
    MessageUtil.ShowTips(sb.ToString());

    而SortedDictionary例子的输出结果如下所示,从中我们可以看到,遍历键的时候,它们已经经过了字母从大到小进行排序了。

    2、同步的字典集合 SyncDictionary。  

    实现效果

    1) 现同步的字典集合操作。 一个同步的字典提供一个线程安全的字典集合。 
    2) 同步字典对象,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的添加、移除、访问等的冲突,放心使用。 
    3) SyncDictionary类继承了CDictionary类,CDictionary继承了框架的Dictionary类,CDictionary并实现了一些克隆及序列化的接口。SyncDictionary类具有Dictionary类的一切特点,另外他还具备线程安全的特点。

    实现代码

    1)辅助类提供的方法接口如下所示: 

    /// <summary>    
    /// 获取指定键的关联值
    /// </summary>
    /// <param name="key">字典键</param>
    /// <param name="value">当此方法返回值时,如果找到该键,便会返回与指定的键相关联的值;否则,则会返回 value 参数的类型默认值。该参数未经初始化即被传递。</param>
    /// <returns>如果字典对象包含具有指定键的元素,则为 true;否则为false. </returns>
    public new bool TryGetValue(TKey key, out TValue value)

    /// <summary>获取或设置指定键的值</summary>
    /// <returns>与指定键关联的值。如果没有找到指定键,KeyNotFoundException将抛出,操作创建一个有指定键的新元素。</returns>
    /// <param name="key">设定值的键</param>
    /// <exception cref="System.ArgumentNullException">键位空</exception>
    /// <exception cref="System.Collections.Generic.KeyNotFoundException">属性检索和键在集合不存在。</exception>
    public new TValue this[TKey key]

    /// <summary>获取字典对象的键集合</summary>
    public new KeyCollection Keys

    /// <summary>获取字典中值的对象集合</summary>
    public new ValueCollection Values

    /// <summary>获取<see cref="System.Collections.Generic.IEqualityComparer{TKey}"></see> 对象,该对象用来比较字典表键的相等</summary>
    /// <returns>对象<see cref="System.Collections.Generic.IEqualityComparer{TKey}"></see> 通用接口,用来判断当前对象<see cref="T:System.Collections.Generic.Dictionary`2"></see>的相等性,
    /// 并提供键的哈希值.</returns>
    public new IEqualityComparer<TKey> Comparer

    /// <summary>
    /// 获取字典集合中包含键值对的数量
    /// </summary>
    /// <value></value>
    /// <returns>字典集合中所含元素的数目</returns>
    public new virtual int Count

    /// <summary>在集合中移除指定键的元素</summary>
    /// <returns>如果元素被移除返回true,否则为false。如果原始集合中没有发现指定键的元素,也返回false。</returns>
    /// <param name="key">待移除元素的键</param>
    /// <exception cref="System.ArgumentNullException">键为空</exception>
    public new bool Remove(TKey key)

    /// <summary>获取迭代结合的枚举器.</summary>
    public new Enumerator GetEnumerator()

    /// <summary>
    /// 初始化SyncDictionary对象实例
    /// </summary>
    /// <param name="dictionary">字典对象</param>
    public SyncDictionary(CDictionary<TKey, TValue> dictionary)

    /// <summary>
    /// 初始化SyncDictionary对象实例
    /// </summary>
    public SyncDictionary()

    /// <summary>
    /// 为字典表添加指定的键值
    /// </summary>
    /// <param name="key">待添加元素的键</param>
    /// <param name="value">待添加元素的值. 该值可以是空引用类型.</param>
    /// <exception cref="System.ArgumentException">一个具有相同键的元素已经存在于字典</exception>
    /// <exception cref="System.ArgumentNullException">键为空</exception>
    public new void Add(TKey key, TValue value)

    /// <summary>
    /// 获取一个值,指出对集合的存取是否同步(线程安全)
    /// </summary>
    /// <value>如果词典的访问是同步的(线程安全)则为True,否则为false。默认为false。 </value>
    public override bool IsSynchronized

    /// <summary>
    /// 从字典中移除所有的键值
    /// </summary>
    public new void Clear()

    /// <summary>
    /// 实现 <see cref="System.Runtime.Serialization"></see> 接口并返回需要序列化字典<see cref="System.Collections.Generic.Dictionary{TKey, TValue}"></see> 实例的数据。
    /// </summary>
    /// <param name="info">一个 SerializationInfo 对象,它包含序列化Dictionary所需的信息。</param>
    /// <param name="context"> StreamingContext 结构,该结构包含与 Dictionary相关联的序列化流的源和目标。</param>
    /// <exception cref="System.ArgumentNullException">info为空引用</exception>
    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)

    /// <summary>
    /// 初始化SyncDictionary对象实例
    /// </summary>
    /// <param name="info"><see cref="System.Runtime.Serialization.SerializationInfo"></see>对象包含序列化<see cref="System.Collections.Generic.Dictionary{TKey, TValue}"></see>的必要信息。</param>
    /// <param name="context">A <see cref="System.Runtime.Serialization.StreamingContext"></see> 含有与序列化流<see cref="System.Collections.Generic.Dictionary{TKey, TValue}"></see>的源和目标的结构。</param>
    internal SyncDictionary(SerializationInfo info, StreamingContext context): base(info, context)

    /// <summary>
    /// 把ICollection的元素复制到一个KeyValuePair类型的数组,在指定的阵列索引开始。
    /// </summary>
    /// <param name="array">一维数组类型KeyValuePair是从ICollection复制KeyValuePair元素的目标。该数组必须具有从零开始的索引。</param>
    /// <param name="index">array中的从零开始的索引,位于复制开始</param>
    public new void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)

    /// <summary>
    /// 实现 <see cref="System.Runtime.Serialization.ISerializable"></see> 接口并抛出反序列化事件,当反序列化完成的时候。
    /// </summary>
    /// <param name="sender">反序列化事件的源对象</param>
    /// <exception cref="T:System.Runtime.Serialization.SerializationException">在当前字典中关联的该对象为无效对象.</exception>
    public override void OnDeserialization(object sender)

    /// <summary>
    /// 确定指定的键是否包含关键。
    /// </summary>
    /// <param name="key"></param>
    /// <returns>
    /// 如果包含指定的键返回True,否则false。
    /// </returns>
    public new bool ContainsKey(TKey key)

    /// <summary>
    /// 判断<see cref="System.Collections.Generic.Dictionary{TKey, TValue}"></see>是否包含指定的值
    /// </summary>
    /// <param name="value">在字典中待查找的值,如果值是引用类型则可以为null。</param>
    /// <returns>
    /// 如果 <see cref="System.Collections.Generic.Dictionary{TKey, TValue}"></see> 包含指定值的元素返回true,否则返回false.
    /// </returns>
    public new bool ContainsValue(TValue value)



    2)本辅助类主要是用来方便实辅助类SyncDictionary的使用例子代码如下所示,由于SyncDictionary线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。

    SyncDictionary<string, string> syncDict = new SyncDictionary<string, string>();    
    syncDict.Add("A", "testA");
    syncDict.Add("C", "testC");
    syncDict.Add("B", "TestB");

    //通过键访问
    StringBuilder sb = new StringBuilder();
    foreach (string key in syncDict.Keys)
    {
    sb.AppendFormat("{0}:{1}\r\n", key, syncDict[key]);
    }
    sb.AppendLine();
    MessageUtil.ShowTips(sb.ToString());

    输出结果如下所示,我们看到,他们虽然可以通过键和索引进行访问,但是他们的顺序不会发生变化。

    3) 另外它的线程安全,使得其多线程之间的操作也是非常安全、高效的。

    SyncDictionary<string, string> syncDict = new SyncDictionary<string, string>();    
    private void btnSyncTest_Click(object sender, EventArgs e)
    {
    for (int i = 0; i < 5; i++)
    {
    Thread thread = new Thread(new ThreadStart(AddSyncDict));
    thread.Start();
    thread.Join();//等待线程完成才返回主线程
    }

    StringBuilder sb = new StringBuilder();
    foreach (string key in syncDict.Keys)
    {
    sb.AppendFormat("Key:{0} Value:{1} \r\n", key, syncDict[key]);
    }
    MessageUtil.ShowTips(sb.ToString());
    }

    private void AddSyncDict()
    {
    string key = new Random().Next().ToString();
    if (!syncDict.ContainsKey(key))
    {
    syncDict.Add(key, DateTime.Now.ToString());
    }
    Thread.Sleep(100);
    }

    多线程之间操作的运行效果如下所示

    3、同步、有序的字典集合 SyncOrderedDictionary。  

    实现效果

    1)本辅助类主要是用来方便实现同步、有序的字典集合操作。 一个同步的字典提供一个线程安全的字典集合;一个有序的字典是一个集合类,它里面的项目可以通过其索引或他们的键进行操作。。 
    2) 同步字典对象,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的添加、移除、访问等的冲突,放心使用。 
    3) 有序集合对象,特点是查找非常高效率,并且提供了强类型的数据操作,不过由于其需要额外在列表中存储数据,因此尽量减少插入或者删除集合对象。 
    4) 有序的字典集合,虽然存在一些缺点,但是提供了一个非常灵活和用户友好数据结构,允许通过键值或索引进行访问。 
    5) SyncOrderedDictionary类继承了OrderedDictionary类,具有OrderedDictionary类的一切特点,另外他还具备线程安全的特点。

    实现代码

    1)辅助类提供的方法接口如下所示: 

     接口综合了以上两种(同步、有序)字典类的特点,接口代码不在粘贴出来。

    2)辅助类SyncOrderedDictionary的使用例子代码如下所示,由于SyncOrderedDictionary在检索的时候效率很高,而且可以通过索引和键进行定位,提供了较好的操作性和方便性。另外由于线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。

    SyncOrderedDictionary<string, string> syncDict = new SyncOrderedDictionary<string, string>();    
    syncDict.Add("A", "testA");
    syncDict.Add("C", "testC");
    syncDict.Add("B", "TestB");

    //通过键访问
    StringBuilder sb = new StringBuilder();
    foreach (string key in syncDict.Keys)
    {
    sb.AppendFormat("{0}:{1}\r\n", key, syncDict[key]);
    }
    sb.AppendLine();

    //通过索引访问
    for (int i = 0; i < syncDict.Keys.Count; i++)
    {
    sb.AppendFormat("{0}:{1}\r\n", i, syncDict[i]);
    }
    MessageUtil.ShowTips(sb.ToString());

    输出结果如下所示,我们看到,他们虽然可以通过键和索引进行访问,但是他们的顺序不会发生变化。

    4、同步的列表集合 SyncList。  

    实现效果

    1) 本辅助类主要是用来方便实现同步列表集合操作。 一个同步的列表集合提供一个线程安全的列表集合; 
    2)同步字典对象,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的添加、移除、访问等的冲突,放心使用。

    实现代码

    1)辅助类提供的方法接口如下所示,该类继承一个自定义的CList,CList实现了克隆等一些接口,SyncList的函数接口定义如下: 

    /// <summary>    
    /// 初始化一个同步列表对象实例
    /// </summary>
    public SyncList()

    /// <summary>
    /// 初始化一个同步列表对象实例
    /// </summary>
    /// <param name="list">The list.</param>
    public SyncList(CList<T> list)

    /// <summary>
    /// 获取一个值,判断<see cref="System.Collections.ICollection"></see> 是否为同步的(线程安全).
    /// </summary>
    /// <value>如果为同步(线程安全)的,返回true,否则false. 默认为false </value>
    /// <returns>如果为同步(线程安全)的,返回true,否则false</returns>
    public override bool IsSynchronized

    /// <summary>添加一个对象到 <see cref="System.Collections.Generic.List<T>"></see>末尾.</summary>
    /// <param name="item">待添加的对象. 值可以为空引用类型。</param>
    public new void Add(T item)

    /// <summary>添加一个集合到 <see cref="System.Collections.Generic.List<T>"></see>末尾</summary>
    /// <param name="collection">其集合元素待添加到 <see cref="System.Collections.Generic.List<T>"></see>末尾的集合.
    /// 集合本身不能为空,但如果类型TKey是一个引用类型,则它包含的元素可以为空</param>
    /// <exception cref="System.ArgumentNullException">集合为空</exception>
    public new void AddRange(IEnumerable<T> collection)

    /// <summary>
    /// 为当前集合返回一个只读的<see cref="System.Collections.Generic.IList<T>"></see> 包装类。
    /// </summary>
    public new ReadOnlyCollection<T> AsReadOnly()

    /// <summary>
    ///<see cref="System.Collections.Generic.List<T>"></see>集合中移除所有对象。
    /// </summary>
    public new void Clear()

    /// <summary>判定指定的元素是否在 <see cref="System.Collections.Generic.List<T>"></see> 中.</summary>
    /// <returns>如果元素在 <see cref="System.Collections.Generic.List<T>"></see>中存在返回true,否则返回false.</returns>
    /// <param name="item">待查找的元素,如果值为引用类型则可以为null</param>
    public new bool Contains(T item)

    /// <summary>
    /// 转换当前 <see cref="System.Collections.Generic.List<T>"></see> 的元素到另外的类型,并返回包含转换后的元素列表。
    /// </summary>
    /// <returns>一个<see cref="System.Collections.Generic.List<T>"></see>集合,包含当前集合转换后的元素。</returns>
    /// <param name="converter">每个元素从一种类型到另一种类型的转换委托</param>
    /// <exception cref="System.ArgumentNullException">converter 为 null.</exception>
    public new CList<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)

    /// <summary>复制整个 <see cref="System.Collections.Generic.List<T>"></see> 到一个一维数组中</summary>
    /// <param name="array">一维数组,从列表中复制元素的目标对象。该数组必须具有从零开始的索引。</param>
    /// <exception cref="System.ArgumentException">源列表中元素的数量大于目标数组能容纳的数量</exception>
    /// <exception cref="System.ArgumentNullException">array 为 null.</exception>
    public new void CopyTo(T[] array)

    /// <summary>复制整个 <see cref="System.Collections.Generic.List<T>"></see> 到一个一维数组中</summary>
    /// <param name="array">一维数组,从列表中复制元素的目标对象。该数组必须具有从零开始的索引。</param>
    /// <param name="arrayIndex">array中的从零开始的索引,位于复制开始。</param>
    /// <exception cref="System.ArgumentException">arrayIndex 大于或等于array数组长度;或源列表的元素数量大于目标array数组从arrayIndex到结束的可用空间</exception>
    /// <exception cref="System.ArgumentOutOfRangeException">arrayIndex 小于等于 0.</exception>
    /// <exception cref="System.ArgumentNullException">array 为 null.</exception>
    public new void CopyTo(T[] array, int arrayIndex)

    /// <summary>
    /// 从列表中复制一个范围内的元素到一个相容的一维数组中。以指定的目标索引开始。
    /// </summary>
    /// <param name="index">在从零开始的索引,位于复制开始的源。</param>
    /// <param name="array">一维数组,从列表中复制元素的目标对象。该数组必须具有从零开始的索引。</param>
    /// <param name="arrayIndex">array中的从零开始的索引,位于复制开始。</param>
    /// <param name="count">待复制的元素数量.</param>
    /// <exception cref="System.ArgumentNullException">array 为 null. </exception>
    /// <exception cref="System.ArgumentOutOfRangeException">index 小于 0;或者arrayIndex 小于0;或者count 小于 0. </exception>
    /// <exception cref="System.ArgumentException">index 大于或等于源列表的数量。或者arrayIndex 大于或等于数组array的长度。或者从index到源列表结束的元素数量大于从 arrayIndex 到数组array结束的可用空间。 </exception>
    public new void CopyTo(int index, T[] array, int arrayIndex, int count)

    /// <summary>
    /// 判定<see cref="System.Collections.Generic.List<T>"></see>是否包含符合定义在指定predicate的条件中包含有元素。</summary>
    /// <returns>如果列表中包含指定条件的元素,返回true,否则为false。</returns>
    /// <param name="match">定义元素的条件来搜索对象的委托</param>
    /// <exception cref="System.ArgumentNullException">match 为 null.</exception>
    public new bool Exists(Predicate<T> match)

    /// <summary>根据定义条件查询一个元素,并返回第一个在整个列表中出现的元素.</summary>
    /// <returns>根据查询条件,第一个在整个列表中出现的元素,如果没有找到,返回Tkey类型的默认值。</returns>
    /// <param name="match">定义元素的条件来搜索的委托</param>
    /// <exception cref="System.ArgumentNullException">match 为 null.</exception>
    public new T Find(Predicate<T> match)

    /// <summary>获取指定Predicate定义的条件相匹配的所有元素。</summary>
    /// <returns>如果遭到元素,返回指定Predicate定义的条件相匹配的所有元素列表,否则返回一个空列表。</see>.</returns>
    /// <param name="match">定义元素的条件来搜索的委托</param>
    /// <exception cref="System.ArgumentNullException">match 为 null.</exception>
    public new CList<T> FindAll(Predicate<T> match)
    。。。。。。。。。。。。。。。。。

      

    2)辅助类SyncList的使用例子代码如下所示,由于线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。

    SyncList<string> syncList = new SyncList<string>();    
    private void btnSyncTest_Click(object sender, EventArgs e)
    {
    for (int i = 0; i < 5; i++)
    {
    Thread thread = new Thread(new ThreadStart(AddSyncList));
    thread.Start();
    thread.Join();//等待线程完成才返回主线程
    }

    StringBuilder sb = new StringBuilder();
    foreach (string item in syncList)
    {
    sb.AppendFormat("item:{0} \r\n", item);
    }
    MessageUtil.ShowTips(sb.ToString());
    }

    private void AddSyncList()
    {
    string key = new Random().Next().ToString();
    syncList.Add(key);
    Thread.Sleep(100);
    }

    输出结果如下所示。


    5、线程安全的先进先出队列辅助类 Fifo。  

    实现效果

    1) 本辅助类主要是用来方便实现线程安全的先进先出队列操作。 
    2)线程安全的先进先出队列,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的进队、出队等的冲突,放心使用。 
    3)Fifo类组合了先进先出的Queue类,提供了线程安全的操作,称为队列或环形缓冲区,这是一种采用先进先出结构(FIFO)的数据结构。现实生活中这种结构应用得非常广泛。比如某些公司的货仓管理系统,要求将先生产的货物先出货,后生产的货物后出货。另外一种场景就是Socket数据包处理的时候,我们一般是把他放到Fifo队列里面,实现先进先出的合理处理。

    实现代码

    1)辅助类提供的方法接口如下所示: 

    /// <summary>    
    /// 队列中目前存在个数
    /// </summary>
    public int Count

    /// <summary>
    /// 队列的最大容量
    /// </summary>
    public int MaxCount

    /// <summary>
    /// 重新设置队列的最大容量
    /// </summary>
    /// <param name="MaxCount">大于1的整数</param>
    public void ResetMaxCount(int MaxCount)

    /// <summary>
    /// 元素进队, 将指定的对象值添加到队列的尾部
    /// </summary>
    /// <param name="obj">T 型的参数</param>
    public void Append(T obj)

    /// <summary>
    /// 元素出队,即移除队列中开始的元素,按先进先出(FIFO)的规则,从前向后移除元素。
    /// </summary>
    /// <returns></returns>
    public T Pop()

    2)辅助类Fifo的使用例子代码如下所示,由于Fifo线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。 

    /// <summary>    
    /// 组包后数据的队列(先进先出)
    /// </summary>
    protected Fifo<PreData> _preDataFifo = new Fifo<PreData>(50000);

    /// <summary>
    /// 接收处理数据
    /// </summary>
    /// <param name="data">包体</param>
    public void AppendPreData(PreData data)
    {
    this._preDataFifo.Append(data);
    }

    /// <summary>
    /// 数据处理
    /// </summary>
    protected virtual void PreDataHandle()
    {
    try
    {
    while (true)
    {
    PreData data = _preDataFifo.Pop();
    if (data != null)
    {
    PreDataHandle(data);
    }
    }
    }
    catch(Exception ex)
    {
    string message = string.Format("[{0}.PreDataHandle] desc:接收器处理异常->{1}", this._Name, ex.ToString());
    Log.WriteError(message, ex.ToString(), true);
    }
    }

    /// <summary>
    /// 对每一个包体的数据进行处理
    /// </summary>
    /// <param name="data">包体</param>
    public virtual void PreDataHandle(PreData data)
    {
    }


    6、各种常用数组排序操作辅助类 SortHelper。  

    实现效果

     1) 本辅助类主要是用来方便实现各种常用数组排序操作,包括冒泡排序法、插入排序法、选择排序法、希尔排序法、快速排序法。 

    2) 本辅助类提供一些常用的排序操作,也可以作为学习排序的基础教程。

    实现代码

    1)辅助类提供的方法接口如下所示: 

    /// <summary>    
    /// 冒泡排序法
    /// </summary>
    /// <param name="list">待排序数组</param>
    public static void BubbleSort(int[] list)

    /// <summary>
    /// 插入排序法
    /// </summary>
    /// <param name="list">待排序数组</param>
    public static void InsertionSort(int[] list)

    /// <summary>
    /// 选择排序法
    /// </summary>
    /// <param name="list">待排序数组</param>
    public static void SelectionSort(int[] list)

    /// <summary>
    /// 希尔排序法
    /// </summary>
    /// <param name="list">待排序数组</param>
    public static void ShellSort(int[] list)

    /// <summary>
    /// 快速排序法
    /// </summary>
    /// <param name="list">待排序数组</param>
    /// <param name="low">低位</param>
    /// <param name="high">高位</param>
    public static void QuickSort(int[] list, int low, int high)

    2)辅助类SortHelper的使用例子代码如下所示。

    private void btnSort_Click(object sender, EventArgs e)    
    {
    //冒泡排序法
    int[] list = new int[10] { 0, 1, 2, 3, 4, 9, 8, 7, 6, 5 };
    SortHelper.BubbleSort(list);
    StringBuilder sb = new StringBuilder();
    foreach (int i in list)
    {
    sb.AppendFormat("{0},", i);
    }
    MessageUtil.ShowTips(sb.ToString());

    //插入排序法
    list = new int[10] { 0, 1, 2, 3, 4, 9, 8, 7, 6, 5 };
    SortHelper.InsertionSort(list);
    sb = new StringBuilder();
    foreach (int i in list)
    {
    sb.AppendFormat("{0},", i);
    }
    MessageUtil.ShowTips(sb.ToString());
    }

    其他的接口排序差不多也是如此调用和结果的,只是在排序效率上有所差异。

    主要研究技术:代码生成工具、Visio二次开发、送水管理软件等共享软件开发
    专注于Winform开发框架、WCF开发框架的研究及应用。
      转载请注明出处:
    撰写人:伍华聪  http:
    //www.iqidi.com 
        
     
     
     
     

    posted on 2012-03-25 17:00 伍华聪 阅读(721) 评论(4) 编辑 收藏

    评论

    #1楼  回复 引用 查看   

    LZ的线程安全,我没有看到具体实现,不过,从用户上来讲,仅仅是实现了数据线程安全,并不是完全的线程安全。我写了一篇关于真正线程安全的文章:《确保真正的线程安全——微软为什么不提供线程安全库》。
    2012-03-25 17:49 | 道法自然      

    #2楼  回复 引用 查看   

    学习了,MARK一下。
    2012-03-25 18:56 | GreySky      

    #3楼  回复 引用 查看   

    持续关注,顶一下,好样的。

    #4楼  回复 引用 查看   

    赞一个,伍老师的贴都很实际。
    2012-03-25 21:13 | pulihe      

    导航

    匿名函数

      顾名思义就是没有名字的函数

    下面说一下它的两个用途:

    1. 你可以把匿名函数作为一个参数传递给其它函数。
    2. 你可以定义一个匿名函数并立马执行它

    回调函数

      因为函数就跟那些可以分配给变量的数据一样,它可以定义,删除,拷贝,所以也可以作为参数传递给函数,简单来说回调函数就是把函数作为参数来用

    看一下下面的例子,也是匿名函数的用途之一

    <script type="text/javascript">        

        function one() {  return 1;  }        

        function two() {  return 2; }

            function sum(a, b) { return a() + b(); }

            document.write("把函数当作参数:" + sum(one, two) + '<br/>');        

        document.write("把匿名函数当作参数:" + sum(one, function () { return 1; }) + '<br/>');    

    </script>

    自调用函数

      目前为止,我们已经讨论了把匿名函数当成回调函数来使用,现在让我们匿名函数的另一个用途——定义后马上调用,下面是一个例子:

    <script type="text/javascript"> 

       ( 

        function () { 

          function hello() { return 2; }

                     document.write(hello()); 

        }        

      )()

            var name = "Jeff";        

        //带参数的        

      (            

         function (param) {                

                    document.write(param);           

        }        

      )(name)                

    </script>

    1. 使用自调用的匿名函数的理由是做一些工作但不需要创建一些全局的变量。
    2. 一个缺点是,很明显就是你不能调用这个函数2 次(除非你把它放在一个循环或者其它函数里面)。这使得自调用的匿名函数非常适合做一次性或者初始化性质的工作。
  • 相关阅读:
    苹果mac shell 终端 命令行快捷键——行首行尾
    mac 编译ffmpeg真简单!
    (2)小彩灯接收数据解析
    JSON数据解析(自写)
    ESP-手机--双向通信模式
    史上最全脉搏心率传感器PulseSensor资料(电路图+中文说明书+最全源代码)
    OpenSCAD 大白
    用OpenSCAD設計特製的遊戲骰子
    如何使用openscad绘制一个简单的键帽.
    OpenSCAD(1)基础教程
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2417203.html
Copyright © 2011-2022 走看看