我有一个通用列表如下
public static readonly List<Customer> Customers = new List<Customer>();
Run Code Online (Sandbox Code Playgroud)
我正在使用以下方法:
.Add
.Find
.FirstOrDefault
Run Code Online (Sandbox Code Playgroud)
最后2个是LINQ扩展.
我需要使这个线程安全的能够运行容器类的多个实例.
怎么实现呢?
在使用LogicalCallContext跨线程共享某些数据时,我们遇到了下面的堆栈跟踪异常
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Hashtable.HashtableEnumerator.MoveNext()
at System.Runtime.Remoting.Messaging.LogicalCallContext.Merge(LogicalCallContext lc)
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
Run Code Online (Sandbox Code Playgroud)
我在MSDN中读取EndInvoke调用时CallContext跨线程合并.我的问题是Hashtable内部不CallContext支持并发.如果它不支持我们应该CallContext在第一点使用吗?如果是,那么有任何指导方针.
任何人都可以解释我什么时候能看到这个堆栈跟踪
如果您可以分享,这种情况的示例会更有帮助.
如果我有一个实例,我使用该属性还是 LINQConcurrentDictionary是否重要?我宁愿写,而不是我认为更具描述性的。CountAny()dict.Any()dict.Count > 0Any()
我只关心正确性,而不关心性能。用例是
void process()
{
if (concurrentDictionary.Count <= 0) // or !Any() ?
return; // dictionary is empty, nothing to do
// ...
}
Run Code Online (Sandbox Code Playgroud) class Sample
{
private List<int> _list;
public List<int> List
{
get
{
return _list.Select(p => p + p).Where(q => q % 2 == 0).ToList();
}
}
public void Add(int n)
{
_list.Add(n);
}
public void Remove(int n)
{
_list.Remove(n);
}
}
Run Code Online (Sandbox Code Playgroud)
我在多线程环境中遇到类似于上面的情况Add,Remove并且List同时由多个线程访问.
在某些情况下Collection was modified; enumeration operation may not execute会抛出Listgetter,这在线程可以在Select/Where操作执行时添加/删除时有意义.
在调用期间,列表是否可以被另一个线程修改ToList()?意思是,会改变吸气剂
return _list.ToList().Select(p => p + p).Where(q => q % 2 == 0);
Run Code Online (Sandbox Code Playgroud)
够了,还是我需要求助于锁定 _list