ObjectCache CachedObjectRemovedCallback не се извиква?

Имам WCF услуга, която внедрява персонализиран ObjectCache за кеширане на COM обект на трета страна за взаимодействие със среда 3270.

Този обект на трета страна работи на лицензиран модел, така че е наложително моят RemovedCallBack да се извиква всеки път, когато даден обект бъде премахнат от кеша, за да се освободят лицензи.

Проблемът ми е, че продължавам да получавам използвани лицензи, но нищо не остава в ObjectCache. Изглежда, че елементите се премахват от кеша, но не удрят обратното извикване. Възможно ли е това? Ако моите кеширани обекти се изчистват от GC, биха ли засегнали и обратното извикване?

Ето моята реализация:

private static readonly ObjectCache cache = MemoryCache.Default;

Елементите се добавят към кеша с помощта на:

   public void AddToCache(String cacheKeyName, object cacheObject, int expiryMinutes)
        {
            callback = CachedObjectRemovedCallback;

            // Sliding expiration
            policy = new CacheItemPolicy
            {
                Priority = CacheItemPriority.Default,
                SlidingExpiration = TimeSpan.FromMinutes(expiryMinutes),
                RemovedCallback = callback
            };

            // Add to cache
            cache.AddOrGetExisting(cacheKeyName, cacheObject, policy);
        }

и премахнато обратно извикване:

private CacheEntryRemovedCallback callback;
private static void CachedObjectRemovedCallback(CacheEntryRemovedArguments arguments)
        {
            // Always check if the object is a customtype, and if so, release the session/license
            if (arguments.CacheItem != null && IsCustomType(arguments.CacheItem.Value))
            {
                // Release the custom session
                ICustomType customType= (ICustomType)arguments.CacheItem.Value;
                customType.ReleaseSession();
            }
        }

person gibbo    schedule 28.12.2013    source източник
comment
Потвърдихте ли, че обратното ви обаждане не се извиква, или просто гадаете?   -  person Michael Edenfield    schedule 28.12.2013
comment
Имам реализирано регистриране в обратното извикване и получавам регистрирани записи, но просто предполагам, че някои от тях не се извикват.   -  person gibbo    schedule 28.12.2013
comment
Също така, опитвали ли сте UpdateCallback, който трябва да бъде извикан точно преди записът да бъде премахнат?   -  person Michael Edenfield    schedule 28.12.2013
comment
Гледах UpdateCallback, но не съм сигурен доколко това би ми помогнало, освен ако не съм в някакво състезателно състояние.   -  person gibbo    schedule 28.12.2013
comment
Възможно ли е вашето обратно извикване да бъде извикано, но операторът ви if някак си се проваля?   -  person Michael Edenfield    schedule 28.12.2013
comment
нека да продължим тази дискусия в чата   -  person gibbo    schedule 28.12.2013


Отговори (1)


Мисля, че много по-добро решение на този проблем е да се избегне изцяло премахнато обратно извикване и да се обвие вашия COM обект с персонализиран клас, който има финализатор за извършване на извикването ReleaseSession(). Още по-добре обаче би било да внедрите някакъв вид групиране на обекти за вашите COM обекти.

В текущата ви реализация (използвайки премахнато обратно извикване), е възможно някой да извади обекта от кеша и преди да приключи с него, кешът решава да изреже, премахвайки същия обект от кеша.

Има някои опасности при извършването на COM извиквания от нишката на финализатора (STA обекти може да блокират финализатора, ако нишката STA не изпомпва например), но не по-лоши от текущата ви реализация.

person Steve    schedule 28.12.2013