110,502
社区成员
发帖
与我相关
我的任务
分享
public class Test
{
public string isok;
public string isfine;
}
ConcurrentBag<Test> MyTest = new ConcurrentBag<Test>();
private void button2_Click(object sender, EventArgs e)
{
for(int i=0;i<3;i++)
{
Test TestEntity = new Test();
TestEntity.isok = "A" + i.ToString();
TestEntity.isfine = "B" + i.ToString();
MyTest.Add(TestEntity);
}
Test ttt = MyTest.First(p => p.isok.Equals("A1") == true);
if (ttt != null)
{
MyTest.TryTake(out ttt);
}
}
static void Main(string[] args)
{
BlockingCollection<string> cachedQueue= new BlockingCollection<string>();
AutoResetEvent stopAddEvent = new AutoResetEvent(false);
//start producer task
Task.Factory.StartNew(() =>
{
Console.WriteLine($"Start add item:{DateTime.Now:yyyy-MM-dd,hh:mm:ss,fff}");
while (!stopAddEvent.WaitOne(100))
{
cachedQueue.Add($"{Guid.NewGuid()}");
}
cachedQueue.CompleteAdding();
Console.WriteLine($"Complete add item:{DateTime.Now:yyyy-MM-dd,hh:mm:ss,fff}");
});
//start comsumer task
Task.Factory.StartNew(() =>
{
foreach(var item in cachedQueue.GetConsumingEnumerable())
{
Console.WriteLine($"Consuming {item}");
}
Console.WriteLine($"All items consumed:{DateTime.Now:yyyy-MM-dd,hh:mm:ss,fff}");
});
//stop produce item after 5s
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
Console.WriteLine($"Will stop add item:{DateTime.Now:yyyy-MM-dd,hh:mm:ss,fff}");
stopAddEvent.Set();
});
Console.Read();
}
public class User
{
public int id { get; set; }
}
static void Main(string[] args)
{
//测试数据
ConcurrentBag<User> list = new ConcurrentBag<User>();
User u1=new User(){id=1};
User u2=new User(){id=2};
User u3=new User(){id=3};
list.Add(u1);
list.Add(u2);
list.Add(u3);
//3个
Console.WriteLine(list.Count);
//移除id=1的
User u=new User() { id = 1 };
list.TryTake(out u);
//2个
Console.WriteLine(list.Count);
Console.ReadLine();
}
//说明:PAIDMergeStatus是自定义的类,也就是变通实现线程安全的List<PAIDMergeStatus>
//PAIDMergeStatus类中必须要有一个int类型的唯一值的字段,这个字段作为ConcurrentDictionary的key
public class ClassForLock
{
public static ConcurrentDictionary<int, PAIDMergeStatus> _PAIDMergeStatus = new ConcurrentDictionary<int, PAIDMergeStatus>();
public static List<T> GetAllFromCache<T>()
{
if (typeof(T) == typeof(PAIDMergeStatus))
{
return _PAIDMergeStatus.Values.ToList() as List<T>;
}
return null;
}
public static void AddOrUpdateForPA<T>(T _Data)
{
if (typeof(T) == typeof(PAIDMergeStatus))
{
if (_PAIDMergeStatus != null && _Data != null)
{
PAIDMergeStatus _Temp = _Data as PAIDMergeStatus;
_PAIDMergeStatus.AddOrUpdate(_Temp.PAID, _Temp, (key, oldvalue) => _Temp);
}
}
}
public static void AddOrUpdateForPA<T>(List<T> _List_Data)
{
foreach (T _Data in _List_Data)
{
AddOrUpdateForPA<T>(_Data);
}
}
public static void TryRemoveForPA<T>(int sysid)
{
if (typeof(T) == typeof(PAIDMergeStatus))
{
if (_PAIDMergeStatus != null)
{
PAIDMergeStatus temp = null;
_PAIDMergeStatus.TryRemove(sysid, out temp);
}
}
}
public static void TryRemoveForPA<T>(List<int> sysid)
{
for (int i = 0; i < sysid.Count; i++)
{
TryRemoveForPA<T>(sysid[i]);
}
}
public static void Clear(string _str)
{
if (_str.Equals("PAIDMergeStatus"))
{
_PAIDMergeStatus.Clear();
}
}
public static void OrderByID(string _str)
{
if (_str.Equals("PAIDMergeStatus"))
{
List<PAIDMergeStatus> _TempOrderBy = GetAllFromCache<PAIDMergeStatus>().OrderBy(p => p.PAID).ToList() as List<PAIDMergeStatus>;
Clear("PAIDMergeStatus");
AddOrUpdateForPA<PAIDMergeStatus>(_TempOrderBy);
}
}
}
上面是我自己用的ConcurrentDictionary的办法,
但是存在问题:当我需要对List<PAIDMergeStatus>执行foreach或者for循环的时候,还是必须要用锁,
对这个问题,你们有解决办法吗?
就是因为ConcurrentDictionary还不够完美,所以我才寻求ConcurrentBag有没有完美的办法,看来我的寻求是失败了。
private ConcurrentBag<Test> removedAt(ConcurrentBag<Test> originalCon,string key)
{
ConcurrentBag<Test> result = new ConcurrentBag<Test>();
var temp=originalCon.Where<Test>(t => t.isok != key);
foreach(var t in temp)
{
result.Add(new Test() { isok = t.isok, isfine = t.isfine });
}
return result;
}
//调用
private void button1_Click(object sender, EventArgs e)
{
ConcurrentBag<Test> MyTest = new ConcurrentBag<Test>();
for (int i = 0; i < 3; i++)
{
Test TestEntity = new Test();
TestEntity.isok = "A" + i.ToString();
TestEntity.isfine = "B" + i.ToString();
MyTest.Add(TestEntity);
}
//调用removedAt()后,返回的还是concurrentBag对象
ConcurrentBag<Test> removedColl = removedAt(MyTest, "A1");
foreach (Test t in removedColl)
{
MessageBox.Show(t.isok.ToString() + "-" + t.isfine.ToString());
}
}
这回完全符合lz的要求:删除指定元素。在原来的基础上继续工作,应该最省事
ConcurrentBag<Test> MyTest = new ConcurrentBag<Test>();
for (int i = 0; i < 3; i++)
{
Test TestEntity = new Test();
TestEntity.isok = "A" + i.ToString();
TestEntity.isfine = "B" + i.ToString();
MyTest.Add(TestEntity);
}
var temp1 = MyTest.Where(t => t.isok != "A1");
foreach(Test t in temp1)
{
MessageBox.Show(t.isok.ToString() + "-" + t.isfine.ToString());
}
输出可以达到你的要求