Создать CSOM ClientContext с возможностью повторного использования, например синглтон - PullRequest
6 голосов
/ 22 февраля 2020

У меня есть несколько методов, вызываемых для различных действий пользователя, которые используют ClientContext . Создание его при каждом выполнении метода вызывало проблемы с производительностью.

Поэтому я добавил его как переменную stati c для повторного использования, производительность улучшилась в среднем за 5 секунд, но затем в некоторых методах он начал выдавать случайные проблемы "Конфликт версий" в ExecuteQuery () . Но если я уберу проверку stati c и null, то она обновляется каждый раз, и производительность становится проблемой

Есть ли способ создать один временный объект из этого или, по крайней мере, не при каждом вызове? И каков срок действия ClientContext по умолчанию?

Код для создания объекта ClientContext:

    public class SPConnection
    {
    public static ClientContext SharepointClientContext { get; set; }
    public static ClientContext GetSharePointContext()
    {
        try
        {
            if (SharepointClientContext == null)
            {
                string appId = System.Configuration.ConfigurationManager.AppSettings["appId"];
                string appSecret = System.Configuration.ConfigurationManager.AppSettings["appSecret"];
                string siteUrl = System.Configuration.ConfigurationManager.AppSettings["siteUrl"];

                var authManager = new OfficeDevPnP.Core.AuthenticationManager();
                using (ClientContext clientContext = authManager.GetAppOnlyAuthenticatedContext(siteUrl, appId, appSecret))
                {
                    SharepointClientContext = clientContext;
                    return clientContext;
                }
            }
            else
                return SharepointClientContext;
        }
        catch (Exception ex)
        {
            iChange.Web.API.Authentication.SPConnection.InsertRecordToTableErrorLog("Mucebat:"+ex.Message, ex.StackTrace.ToString());
            throw ex;
        }

    }

Код для одного из методов, потребляющих его:

    public bool UpdateProfilePic(updateprofilepicmodel model)
    {
        using (ClientContext context = SPConnection.GetSharePointContext())
        {
            List list = context.Web.Lists.GetByTitle("Members");
            ListItemCreationInformation info = new ListItemCreationInformation();
            ListItem item = list.GetItemById(model.MemberId);

            item["ProfilePicture"] = model.ProfilepicUrl;
            item.Update();
            context.ExecuteQuery();
            return true;
        }

    }

Ответы [ 3 ]

1 голос
/ 27 февраля 2020

Можете ли вы попробовать использовать ExecuteQueryAsync в сочетании с asyn c задачами для повышения производительности? например,

     public async Task <bool> UpdateProfilePic(updateprofilepicmodel model)
{
    using (ClientContext context = SPConnection.GetSharePointContext())
    {
        List list = context.Web.Lists.GetByTitle("Members");
        ListItem item = list.GetItemById(model.MemberId);
        context.Load(item);
        Task t1 = context.ExecuteQueryAsync();
        await t1.ContinueWith((t) =>
            {
                item["ProfilePicture"] = model.ProfilepicUrl;
                item.Update();
                Task t2 = context.ExecuteQueryAsync();
            });

        await t2.ContinueWith((t) =>
            {
               // do some stuff here if needed
            });

        return true;
    }
}

PS: я не проверял этот код, но в случае, если это работает для вас

0 голосов
/ 27 февраля 2020

Вы не можете использовать ClientContext в качестве объекта c. В коде вы пишете свой код в разделе Использование. Объект ClientContext будет уничтожен, когда выполнение нас с использованием блока будет завершено.

0 голосов
/ 24 февраля 2020

Вы можете попробовать Загрузить элемент списка перед его обновлением. Измените код, как показано ниже, чтобы проверить, работает ли он.

public bool UpdateProfilePic(updateprofilepicmodel model)
{
    using (ClientContext context = SPConnection.GetSharePointContext())
    {
        List list = context.Web.Lists.GetByTitle("Members");
        ListItem item = list.GetItemById(model.MemberId);
        context.Load(item);
        context.ExecuteQuery();
        item["ProfilePicture"] = model.ProfilepicUrl;
        item.Update();
        context.ExecuteQuery();
        return true;
    }
}

Если приведенный выше код не работает, вы можете включить версию списка «Участники» в настройках списка, чтобы проверить, существует ли проблема по-прежнему.

...