내가 can& # 39, t get to the bottom 이유는열 bsc247-3, 디버거, 이 오류가 발생할 것으로 보이지 않는다. 다음은 코드.
이는 WCF (windows server 서비스용입니다. 이 방법은 해당 서비스에 의해 호출됨 노아피서브스크리베르스 있을 때마다 는 데이터 이벤트 (임의의 간격으로 하루에 약 800 배 아니라 매우 자주 -).
이 경우, Windows Forms 클라이언트입니다 구독 구독하셨습니까 ID 가 추가된 것은 삭제될 때 사전에 수신 거부 및 가입자 클라이언트뿐 사전이므로 이 오류가 발생할 때 (또는 이후) 클라이언트여야 수신 거부. 다음에 노아피서브스크리베르스 것으로 보인다 () 메서드를 호출됨 포리치 () 는 루프 실패하면서 제목줄의 오류. 아래 코드는 같이 오류 꽂으십시오 애플리케이션 로그에서는 방법을 씁니다. 수신 거부 및 클라이언트 코드가 실행될 때 디버거 bsc247-3 좋았소
이 코드를 문제가 표시됩니까? 스레드 사전을 만들 필요가 있습니까?
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class SubscriptionServer : ISubscriptionServer
{
private static IDictionary<Guid, Subscriber> subscribers;
public SubscriptionServer()
{
subscribers = new Dictionary<Guid, Subscriber>();
}
public void NotifySubscribers(DataRecord sr)
{
foreach(Subscriber s in subscribers.Values)
{
try
{
s.Callback.SignalData(sr);
}
catch (Exception e)
{
DCS.WriteToApplicationLog(e.Message,
System.Diagnostics.EventLogEntryType.Error);
UnsubscribeEvent(s.ClientId);
}
}
}
public Guid SubscribeEvent(string clientDescription)
{
Subscriber subscriber = new Subscriber();
subscriber.Callback = OperationContext.Current.
GetCallbackChannel<IDCSCallback>();
subscribers.Add(subscriber.ClientId, subscriber);
return subscriber.ClientId;
}
public void UnsubscribeEvent(Guid clientId)
{
try
{
subscribers.Remove(clientId);
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine("Unsubscribe Error " +
e.Message);
}
}
}
foreach(Subscriber s in subscribers.Values)
수
foreach(Subscriber s in subscribers.Values.ToList())
호출하십시오 "고 설명했다. 발 주스토리스트 () 는 그 값을 "고 설명했다. 시작할 때 별도의 목록을 값을 포리치. 아무것도아니야 건드릴 수 없어 이 목록 (# 39, t it doesn& 갖추지 변수 이름을!), 그래서 아무것도아니야 루프 내에 파일을 수정할 수 있습니다.
제 생각에는, 다른, 보다 효율적으로 할 수 있는 것은 아무 것도 할 수 있다, 저장한 나열하십시오 너희가운데 " removed". 대상. 다음 주 업무는 완료했으면 루프 (네스토리스트 없이 ()), 수, removed" " 통해 다른 루프 등을 할 수 있습니다. 목록, 각 항목을 제거하기 때문에 발생합니다. 그래서 클래스에 추가했는지:
private List<Guid> toBeRemoved = new List<Guid>();
그런 다음 변경하십시오:
public void NotifySubscribers(DataRecord sr)
{
toBeRemoved.Clear();
...your unchanged code skipped...
foreach ( Guid clientId in toBeRemoved )
{
try
{
subscribers.Remove(clientId);
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine("Unsubscribe Error " +
e.Message);
}
}
}
...your unchanged code skipped...
public void UnsubscribeEvent(Guid clientId)
{
toBeRemoved.Add( clientId );
}
이렇게 하면 문제를 해결할 것을 막을 수 있을 뿐 아니라, 이 중에서 사전을 만들 필요가 없습니다 렉시한테서 바뀌엇어요 원하는거요 비싸다구요 많은 경우 가입자 할 수 있다. 가정하여 제거할 수 있는 전체 가입자 목록 주어진 이터레이션은 목록에서 이 보다 더 빨라야 한다. 물론 이 경우 언제든지 확인할 수 있는 there& 프로필링하려면 that& # 39, s, s # 39 에 모든 것에 대한 구체적인 사용 할 수 없다.
이 오류는 < /h3>;;; 왜 < h3>? 일반적으로 .Net 컬렉션을 기술입니까 열거됩니다 및 수정날짜 동시에건간에 지원하지 않습니다. 이 중 모음집 수정하십시오 열거도 시도할 경우 예외를 던진다. 따라서 이 문제를 뒤로 목록 / 사전을 통해 우리는 루프을 수정하십시오 오류:, 동시에 같은 수 없다. < h3> 중 solutions< /h3>;;; 만약 우리가 그 키를 사용하여 바뀌엇어요 사전 반복할 수 있기 때문에, 우리는 수정하십시오 병렬로 사전 객체에는 전체 반복을 키 컬렉션 및 아닌 사전 (및 해당 키를 반복 취합은).
< h3> Example< /h3>;;;
//get key collection from dictionary into a list to loop through
List<int> keys = new List<int>(Dictionary.Keys);
// iterating key collection using a simple for-each loop
foreach (int key in keys)
{
// Now we can perform any modification with values of the dictionary.
Dictionary[key] = Dictionary[key] - 1;
}
이것은 블로그 포스트 이 솔루션에 대한.
스택 오버플로 의 경우 및 심층 분석: 왜 이 오류는?
전 그 때 나는 '를 사용한 것은 같은 문제를 해결할 루프' 포리치 '대신'.
// foreach (var item in itemsToBeLast)
for (int i = 0; i < itemsToBeLast.Count; i++)
{
var matchingItem = itemsToBeLast.FirstOrDefault(item => item.Detach);
if (matchingItem != null)
{
itemsToBeLast.Remove(matchingItem);
continue;
}
allItems.Add(itemsToBeLast[i]);// (attachDetachItem);
}
그러나 이 그 중 하나는 다양한 옵션을 i& # 39, ve seen 엔드입니다 다는일은 최고라니까요
ListItemCollection collection = new ListItemCollection();
foreach (ListItem item in ListBox1.Items)
{
if (item.Selected)
collection.Add(item);
}
그럼 통해 단순히 루프 컬렉션.
한 점을 유념하십시오 리스티템콜레스티온 중복 사용할 수 있습니다. 기본적으로 추가되는 취합은 중복을 막을 수 없다. 중복을 피하기 위해 이 작업을 수행할 수 있습니다.
ListItemCollection collection = new ListItemCollection();
foreach (ListItem item in ListBox1.Items)
{
if (item.Selected && !collection.Contains(item))
collection.Add(item);
}
다음은 전문 외곽진입 구속영장을 특정 것이 특징.
이 시나리오에서의 복제본에 만들기 전에 '사전' (또는 '딕티오나리스발 주') 수 있는 모든 열거도 꽤 많은 비용이 소요됩니다. 이 문제를 해결하는 것이 내 생각이야 같은 여러 열거형 및 대한 재사용합니다 캐싱된 복제본에, 원래 '사전' 을 '한' 리누마레이터 제스쳐놀이처럼 존재한다. 열거자가 캐시되지 복사됨 데이터 및 조사를 시작하기 전에 새로운 열거도 함께 했다. 예외적인 경우에 캐싱된 복제본에 폐기됩니다, 새로운 한 조성된다. 다음은 이 아이디어를 내 구현.
public class SafeEnumerable<T> : IEnumerable<T>, IDisposable
{
private IEnumerable<T> _source;
private IEnumerator<T> _enumerator;
private T[] _cached;
public SafeEnumerable(IEnumerable<T> source)
{
_source = source ?? throw new ArgumentNullException(nameof(source));
}
public IEnumerator<T> GetEnumerator()
{
if (_source == null) throw new ObjectDisposedException(this.GetType().Name);
if (_enumerator == null)
{
_enumerator = _source.GetEnumerator();
_cached = _source.ToArray();
}
else
{
var modified = false;
if (_source is ICollection collection) // C# 7 syntax
{
modified = _cached.Length != collection.Count;
}
if (!modified)
{
try
{
_enumerator.MoveNext();
}
catch (InvalidOperationException)
{
modified = true;
}
}
if (modified)
{
_enumerator.Dispose();
_enumerator = _source.GetEnumerator();
_cached = _source.ToArray();
}
}
foreach (var item in _cached)
{
yield return item;
}
}
public void Dispose()
{
_enumerator?.Dispose();
_enumerator = null;
_cached = null;
_source = null;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public static SafeEnumerable<T> AsSafeEnumerable<T>(this IEnumerable<T> source)
=> new SafeEnumerable<T>(source);
사용 예제:
private static IDictionary<Guid, Subscriber> _subscribers;
private static SafeEnumerable<Subscriber> _safeSubscribers;
//...(in the constructor)
_subscribers = new Dictionary<Guid, Subscriber>();
_safeSubscribers = _subscribers.Values.AsSafeEnumerable();
// ...(elsewere)
foreach (var subscriber in _safeSubscribers)
{
//...
}
현재 이 아이디어를 클래스 '사전' 에서 .NET 죄송합니다. 함께 사용할 수 없기 때문에 핵심 3.0gb 이 클래스 a idfsysobject. 수집은 수정되었음 던지지 않는다 및 ['제거'] 때 열거됩니다 메서드을 2 와 '선택해제합니다' 은 기도하였나니. 다른 모든 컨테이너입니다 있다 내가 점검됩니다 나오는 버텼다. 내가 체크된다면 체계적으로 이러한 클래스: ',', ',', 'ObservableCollection< T> Collection< T> List<;;;;;;', ',', 'HashSet< T> T> SortedSet< T>', ',' 와 ',', T, T, V> Dictionary<, SortedDictionary< V>. 앞에서 말한 두 가지 방법 중 유일하게 .NET 에서는 '사전' 클래스 핵심 무효화하지 않는 열거도.
좋은 곳에 잘 았겠습니다 & 링크가 하나 있습니다. 주어진 솔루션에 대해서도. 그 밖에 있으면 시도하시겠습니까 잡을라는데 이벤트수정적절한 솔루션이므로 부탁이네 게시물로의 frequencyid 이해할 수 있다. 그 밖에 이 같은) 은 주어진 솔루션이므로 게시물로의 솔루션이므로 시도해 볼 수 있습니다 다음
당초 당신꺼에요 참조 링크: https://bensonxion.wordpress.com/2012/05/07/serializing-an-ienumerable-produces-collection-was-modified-enumeration-operation-may-not-execute/, https://bensonxion.wordpress.com/2012/05/07/serializing-an-ienumerable-produces-collection-was-modified-enumeration-operation-may-not-execute/, a href = " < " > < /a>;;;
우리가 사용할 수 있는 닷넷 (.net) 기반 클래스 정의를 객체를 포함하는 열거 유형, 즉 직렬화하지 직렬화할 쉽게 얻을 수 있게 될 것입니다. "라고 취합은 잉바리도프라티온렉세페시옹 " 취합은 수정되었습니다. 열거도 작업을 execute" 수 없습니다. 어디에 코딩) 는 멀티스레드 시나리오에서와. 아래 반복할 경우 에로남이네 직렬화하지 클래스뿐만 취합은 열거자를 통해 이 같은 것으로, 수정할 때 이 문제를 마이그레이션된 취합은 반복할 수 있다.
우리가 먼저 솔루션을 사용할 수 있도록 비호환성의 동기화 솔루션업체 잠급니다 쉽게 할 수 있습니다 한 번에 실행할 수 있는 목록에 연산입니다 객체에는 이벤트여야만 스레드할. 당연히 성능이 저하될 수 있는 경험할 수 있습니다. 해당 객체의 직렬화할 하려면 모음 각각에 대해, 그리고 그들을 좉툑 적용됩니다.
뭐, .Net 4.0 다룰 수 있는 멀티-스레딩 시나리오에서와 유용합니다. 내가 찾은 이 문제를 통해 우리가 직렬화하는 중 취합은 필드 (확인란 MSDN) 클래스, 시행하십시오 콘스해류크루 됩니다. 이는 스레드 안전 및 FIFO 취합은 하면 코드 잠금 무료.
이 클래스의 사용 편의성, 그 물건을 교체하십니까 취합은 유형, 이를 통해 이 코드는 맞게 수정할 수 있어야 합니다. 인큐 사용하여 요소를 추가하려면, 그 끝을 콘스해류크루 제거하시겠습니까 잠급니다 코드입니다. 시나리오 작업 중인 같은 경우에는 아직 제대로 적응하지 못해 몇 차례 더 코드 목록 발생하지만 취합은 합니다 콘스해류크루 를 보다 작은 자연수이다.
브트와, 콘스해류크루 doesn& # 226, t, t # 226 허용할 수 있는 방법을 기본 알고리즘입니다 투명지에 선택해제합니다 인해 doesn& 선택해제한 원자 컬렉션. 그러니 do it yourself, 가장 빠른 방법은 재생성하려면 위한 새로운 빈 콘스해류크루 교체품을.
이 수락됨 bb84 프로토콜 및 잘못된 최악의 경우 그 답을 찾을 수 있습니다. () '중' 토리스트 변경되면 오류로 끝날 수도 있습니다. 또 ',' 잠급니다 고려해야 할 경우 어떤 성능과 스레드 안전 공개 회원, 적절한 솔루션을 사용할 수 있는 [불변 유형은상위] (https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable).
일반적으로 can& 상태를 변경할 수 있는 t # 39 는 불변 유형, 한 번 만들어졌다. 따라서 같은 코드를 살펴봐야 한다.
public class SubscriptionServer : ISubscriptionServer
{
private static ImmutableDictionary<Guid, Subscriber> subscribers = ImmutableDictionary<Guid, Subscriber>.Empty;
public void SubscribeEvent(string id)
{
subscribers = subscribers.Add(Guid.NewGuid(), new Subscriber());
}
public void NotifyEvent()
{
foreach(var sub in subscribers.Values)
{
//.....This is always safe
}
}
//.........
}
공개 회원 경우 사용할 때 유용합니다. 항상 다른 클래스를 수정할 수 있는 '포리치' 에 대한 걱정 없이 불변 유형은상위 컬렉션.