Mercurial > hg > Database > Christie-sharp
view datagear/DataGears.cs @ 46:41aae40a611c
bug fix
author | riono <e165729@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 07 Jan 2022 19:38:49 +0900 |
parents | efb06874a34e |
children |
line wrap: on
line source
using System; using System.Collections.Concurrent; using System.Collections.Generic; using Christie_net.annotation; using Christie_net.datagear.command; using Christie_net.datagear.dg; namespace Christie_net.datagear { public class DataGears { protected SortedDictionary<string, BlockingCollection<DataGear<object>>> dataGears = new SortedDictionary<string, BlockingCollection<DataGear<object>>>(); private readonly object syncObject = new object(); /// <summary> /// 新しいdataGearの追加 /// </summary> /// <param name="key"></param> /// <param name="dg"></param> public void Put(string key, DataGear<object> dg) { lock (syncObject) { if (dataGears.ContainsKey(key)) { dataGears[key].TryAdd(dg); } else { var queue = new BlockingCollection<DataGear<object>>(); queue.TryAdd(dg); dataGears.Add(key, queue); //Console.WriteLine("dict:" + dataGears.Count + " queue:" + dataGears[key].Count); } } } /// <summary> /// DataGeraの取得と削除 /// </summary> /// <param name="key"></param> /// <returns></returns> public object Take(string key) { lock (syncObject) { object data = null; // Queueからの取得は参照渡し DataGear<object> dataGear; //Console.WriteLine("queue num:" + dataGears.Count); if (dataGears[key].TryTake(out dataGear)) { data = dataGear.GetData(); } //Console.WriteLine("count:" + dataGears[key].Count); // DataGeraを削除取り出ししたのでkeyも削除 if (dataGears[key].Count == 0) { dataGears[key].Dispose(); dataGears.Remove(key); } // if (dataGears[key].Count == 0) { // dataGears[key].Dispose(); // } //Console.WriteLine("queue num after:" + dataGears.Count); return data; } } /// <summary> /// DataGeraを削除せずに取得 /// </summary> /// <param name="key"></param> /// <returns></returns> public object Peek(string key) { lock (syncObject) { object data = null; DataGear<object> dataGear; // BlockingCollectionではpeekできないので、中のConcurrentQueueを取り出して操作 ConcurrentQueue<DataGear<object>> queue = new ConcurrentQueue<DataGear<object>>(dataGears[key]); if (queue.TryPeek(out dataGear)) { data = dataGear.GetData(); } return data; } } /// <summary> /// commandによりDataの取得 /// </summary> /// <param name="cm"></param> /// <returns></returns> public object GetData(Command cm) { lock (syncObject) { CommandType type = cm.type; if (type == CommandType.TAKE || type == CommandType.REMOTETAKE) { return Take(cm.key); } else if (type == CommandType.PEEK || type == CommandType.REMOTEPEEK){ return Peek(cm.key); } return null; } } /// <summary> /// Dataを挿入する /// </summary> /// <param name="cm"></param> public void SetData(Command cm) { lock (syncObject) { Put(cm.key, cm.dg); } } /// <summary> /// 既にkeyが含まれているか返す /// </summary> /// <param name="key"></param> /// <returns></returns> public bool ContainsKey(string key) { lock (syncObject) { return dataGears.ContainsKey(key); } } } }