문제
이 síngleton 캐시 개체고 그것을 노출합페이 제공하는 반환하는 개인페이 변수입니다.
나는 정적 방법을 내는 단일 객체 업데이트를 이 멤버변수(에 존재하는 단 하나의 인스턴스'인스턴스의 이 캐시 object).
자의 말하는 일부를 스레드가 현재 반복이페이 변수/부동산하는 동안 내 캐시입 업데이트입니다.나는 그것에게 그렇게 캐시입 업데이트에 새로운 지역 변수하고 마지막으로 설정하면 노출되는 개인 변수의 포인트를 이 새로운 지역 변수가 있습니다.
난 그냥에 대한 참조를 업데이트를 떠나,다른(old)체에서 메모리를 기다리가 선택 GC 지만 내 문제입니다-나는 100%확실하면 어떻게 설정하는 새로운 기준?것 다른 스레드가 갑자기 반복을 통해 새로운 객체 또는 오래된 중 하나 그것을 통해 전달되페이겠습니까?되었을 경우 정상적인 참조 나는'no'.스레드 호출 될 것이 운영에서의 오래된 개체는,하지만 나는 확실하지 않으면 이는 폐쇄니까?
여기에는 클래스 벗었:
internal sealed class SektionCache : CacheBase
{
public static readonly SektionCache Instance = new SektionCache();
private static readonly object lockObject = new object();
private static bool isUpdating;
private IEnumerable<Sektion> sektioner;
static SektionCache()
{
UpdateCache();
}
public IEnumerable<Sektion> Sektioner
{
get { return sektioner; }
}
public static void UpdateCache()
{
// SNIP - getting data, locking etc.
Instance.sektioner = newSektioner;
// SNIP
}
}
해결책
실는 현재 열거 sektioner 계속 열거하는 경우에도 당신은 참조를 업데이트 내에서 단일.거기에 아무것도에 대한 특별한 개체를 구현하는페.
당신은 아마도 추가 휘발성 키워드하 sektioner 드로 당신을 제공하지 않 읽기 잠금 및 여러 스레드 읽기/쓰기.
다른 팁
이후 getter { return sektioner; }
호출하기 전에 새로운 값은 넣어 분야에서,오래된 값이 반환됩니다.그리고,루프 foreach (Sektion s in cache.Sektioner)
값을 사용하여 받은 경우 getter 라,즉이전 값.는 값에 걸쳐 사용될 것이 foreach 다.
첫째 나는 볼 수 없 개체 잠금을 사용하지 않는 lockObject 변수 나를 슬프다.페이지 않은 특별합니다.각 스레드가 있을 것이다 그것의 자신의 복사본을 참조하여 몇 가지의 인스턴스 sektioner 개체입니다.할 수 없습니다 다른 스레드에 영향을 미칠하는 방법입니다.무슨 일이 일어날 것과 오래된 버전의 데이터가 가리키는 sektioner 분야에 크게 의존하자.
내가 생각하는 경우에,당신이 원하는 스레드에 안전 사용해야 합니다 이 방법:
internal sealed class SektionCache : CacheBase
{
//public static readonly SektionCache Instance = new SektionCache();
// this template is better ( safer ) than the previous one, for thread-safe singleton patter >>>
private static SektionCache defaultInstance;
private static object readonly lockObject = new object();
public static SektionCach Default {
get {
SektionCach result = defaultInstance;
if ( null == result ) {
lock( lockObject ) {
if ( null == result ) {
defaultInstance = result = new SektionCache();
}
}
}
return result;
}
}
// <<< this template is better ( safer ) than the previous one
//private static readonly object lockObject = new object();
//private static bool isUpdating;
//private IEnumerable<Sektion> sektioner;
// this declaration is enough
private volatile IEnumerable<Sektion> sektioner;
// no static constructor is required >>>
//static SektionCache()
//{
// UpdateCache();
//}
// <<< no static constructor is required
// I think, you can use getter and setter for reading & changing a collection
public IEnumerable<Sektion> Sektioner {
get {
IEnumerable<Sektion> result = this.sektioner;
// i don't know, if you need this functionality >>>
// if ( null == result ) { result = new Sektion[0]; }
// <<< i don't know, if you need this functionality
return result;
}
set { this.sektion = value; }
}
//public static void UpdateCache()
//{
//// SNIP - getting data, locking etc.
//Instance.sektioner = newSektioner;
//// SNIP
//}
}