Мой IBackingStore должен быть потокобезопасным? - PullRequest
0 голосов
/ 28 июня 2009

Документация библиотеки предприятия гласит:

Благодаря тому, как работает объект Cache, вам гарантировано что любой магазин поддержки будет называться однопоточным способом. это означает, что вам не нужно делать поток реализации безопасен.

А по поводу CacheManager:

Каждый вызов метода осуществляется через Объект CacheManager является потокобезопасным.

Но простой тест доказывает обратное:

Вот мой пользовательский резервный магазин (актуален только метод Add)

public class MyStore : IBackingStore
{
    volatile bool isEntered = false;
    #region IBackingStore Members

    public void Add(CacheItem newCacheItem)
    {
        if(isEntered)
            throw new NotImplementedException();
        isEntered = true;

        Thread.Sleep(1000);

        isEntered = false;

    }

    public int Count
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public void Flush()
    {
        throw new NotImplementedException();
    }

    public System.Collections.Hashtable Load()
    {
        return new System.Collections.Hashtable();
    }

    public void Remove(string key)
    {
        throw new NotImplementedException();
    }

    public void UpdateLastAccessedTime(string key, DateTime timestamp)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    #endregion
}

А вот тест с доступом к тому же CacheManager через два разных потока:

DictionaryConfigurationSource configSource = new DictionaryConfigurationSource();
CacheManagerSettings cacheSettings = new CacheManagerSettings();
configSource.Add(CacheManagerSettings.SectionName, cacheSettings);
CacheStorageData storageConfig = new CacheStorageData("MyStorage", typeof(MyStore));
cacheSettings.BackingStores.Add(storageConfig);
CacheManagerData cacheManagerData = new CacheManagerData("CustomCache", 120, 100, 5, storageConfig.Name);
cacheSettings.CacheManagers.Add(cacheManagerData);
cacheSettings.DefaultCacheManager = cacheManagerData.Name;


CacheManagerFactory cacheFactory = new CacheManagerFactory(configSource);
ICacheManager cacheManager = cacheFactory.CreateDefault();
Thread thread = new Thread(() =>
{
    cacheManager.Add("item1", "odaiu");
});
thread.Start();
cacheManager.Add("item2", "dzaoiudoiza");

Метод Add выполняется два раза в двух разных потоках (поскольку он вызывает исключение NotImplementedException метода Add).

Что-то не так с моим кодом или документация корпоративной библиотеки не так?

Ответы [ 2 ]

0 голосов
/ 19 июля 2010

Я согласен с JaredPar, что в документации указано, что доступ синхронизирован и, следовательно, безопасен. Однако, если вы посмотрите на исходный код для реализации поставленных резервных хранилищ, вы увидите, что он закодирован с ожиданием выполнения в многопоточной среде. Так что, возможно, это случай устаревшей документации.

Следующий отрывок из IsolatedStorageBackingStore в EntLib 5.0 полагает, что реализация 4.1 такая же. Для ясности отрывок является лишь одним из методов, но весь доступ к лежащему в основе IsolatedStorageFile заблокирован.

/// <summary>
/// Adds new item to persistence store
/// </summary>
/// <param name="storageKey">Unique key for storage item</param>
/// <param name="newItem">Item to be added to cache. May not be null.</param>
protected override void AddNewItem(int storageKey, CacheItem newItem)
{
    lock (store)
    {
        string storageLocation = GenerateItemLocation(storageKey);
        IsolatedStorageCacheItem cacheItem =
            new IsolatedStorageCacheItem(store, storageLocation, this.encryptionProvider);
        cacheItem.Store(newItem);
    }
}
0 голосов
/ 28 июня 2009

Поскольку в документации так явно об этом говорится, я бы доверял этой документации.

Ваше доказательство ошибочно в том, что вы создаете явный многопоточный сценарий использования для класса. В конкретном интерфейсе нет ничего, что делает его безопасным для потоков. Так что это, безусловно, не удастся.

Корпоративная библиотека дает гарантию, что они будут управлять интерфейсом безопасным для потока способом. Внутренне они позаботятся о том, чтобы управлять безопасностью потока класса.

Примечание: я не обладаю какими-либо конкретными знаниями об этой библиотеке, но с документацией, которая является явной, я бы доверял ей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...