Когда и где лучше инициализировать надежный сбор?

Сценарий: служба SF с сохранением состояния будет хранить свое состояние в нескольких надежных коллекциях. Statefull SF доступен через удаленное взаимодействие.

Нужно ли «инициализировать» коллекции перед первым использованием (путем вызова StateManager.GetOrAddAsync)? Поможет ли это снизить первый доступ к надежной коллекции или этот шаг делать не обязательно?

Если это рекомендуется сделать, когда это будет подходящее время и место для этого? Самое разумное место — прямо перед бесконечным циклом в RunAsync, но что, если метод, вызываемый через удаленное взаимодействие, будет вызываться до инициализации коллекций? Будет ли какое-либо ухудшение производительности при первом удаленном вызове (когда коллекция будет инициализирована)?

Последнее -> при работе с надежными коллекциями можно хранить ссылку на коллекцию в классе (например, во время инициализации некоторого экземпляра я получу ссылку с помощью StateManager.GetOrAddAsync) и работать только с этой ссылкой или лучше вызвать StateManager.GetOrAddAsync перед каждым вызовом коллекции?

Спасибо за ответы!


person ElDiabloComputatore    schedule 06.12.2016    source источник


Ответы (1)


Нужно ли «инициализировать» коллекции перед первым использованием (путем вызова StateManager.GetOrAddAsync)?

Да, но вам не обязательно делать это, чтобы «разогреть» коллекцию. Вызовите этот метод, если вам действительно нужно получить какие-то данные или вы хотите что-то сохранить.

что, если метод, вызываемый через удаленное взаимодействие, будет вызываться до инициализации коллекций?

Вот почему вам нужно делать StateManager.GetOrAddAsync при каждом вызове службы.

Будет ли какое-либо ухудшение производительности при первом удаленном звонке?

Да. Но это будет незаметно.

при работе с надежными коллекциями можно хранить ссылку на коллекцию в классе

Вы можете хранить ссылку на коллекцию в переменной внутри вызова метода. Вот пример:

    public async Task AddPost(Guid userId, PostId postId)
    {
        try
        {
            var state = await StateManager.GetOrAddAsync<IReliableDictionary<Guid, List<PostId>>>(StateName);

            using (var tx = StateManager.CreateTransaction())
            {
                await state.AddOrUpdateAsync(
                    tx,
                    userId,
                    addValue: new List<PostId> {postId},
                    updateValueFactory: (usrId, oldPostsList) =>
                    {
                        oldPostsList.Insert(0, postId);
                        return oldPostsList;
                    }
                );

                await tx.CommitAsync();
            }
        }
        catch (TimeoutException)
        {
            PostsLogger.Singleton.LogWarning("Add post timeout");
            throw;
        }
        catch (Exception ex)
        {
            PostsLogger.Singleton.LogException(sb.ToString(), ex);
            throw;
        }
    }
person cassandrad    schedule 06.12.2016
comment
Спасибо за ответ! Небольшое дополнение к ссылке на удержание по сравнению с вызовом GetOrAddAsync : Сценарий: класс-оболочка вокруг надежной коллекции. Методы класса создают транзакцию, сохраняют/извлекают данные и фиксируют транзакцию. Достаточно получить ссылку на коллекцию при инициализации/построении обертки или нужно вызывать GetOrAddAsync в каждом методе перед созданием транзакции и работой с коллекцией? Получаете ли вы состояние перед каждым AddPost/RetrievePost? - person ElDiabloComputatore; 07.12.2016
comment
Вы должны вызывать GetOrAddAsync в каждом методе перед созданием транзакции и работой с коллекцией. Ну конечно можно хранить в переменной, но я не уверен, что это сработает, например, при одновременном вызове нескольких методов сервиса. Возможно, это сработает, но я бы не рекомендовал этот подход. Итак, да, вам нужно создавать его при каждом вызове метода службы. Почему бы и нет? Это чертовски дешево по сравнению с другими операциями. Я получаю состояние при каждом вызове AddPost, прямо внутри самого метода. - person cassandrad; 07.12.2016