Частные переменные внутри DelegatingHandler смешивают значения из других запросов

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

public sealed class XYZProxyHandler:DelegatingHandler
{
    private string _var1;
    private string _var2;

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var token = request.Headers.GetCookies().FirstOrDefault().Cookies.FirstOrDefault(x => x.Name.ToLower() == "access_token").Value;
        _var1 = GetVar1(token);
        _var2 = GetVar2(token);

Пытался сделать это как можно более простым из кода, включив в него важный фрагмент кода. В приведенном выше примере кода в идеале _var1 и _var2 должны получать значения своего собственного запроса, но по какой-то причине они иногда получают значения других запросов. У меня есть случаи, когда _var1 получает значение другого запроса, но _var2 получает значение своего собственного запроса и наоборот.

Я сталкивался с таким поведением раньше, когда статическая переменная используется совместно между запросами, но это не статические переменные, и поэтому я не уверен, как это может произойти или как-то связано с реализацией DelegatingHandler.

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

Я не уверен, что у меня туннельное зрение и я не вижу чего-то очевидного или бросающегося в глаза.

Это означает, что несколько запросов совместно используют экземпляры этого непоточно-ориентированного класса. Регистрация его как зависимости с ограниченной областью должна исправить это. Или, если реальный код очень похож на этот, переместите объявления переменных в метод вместо использования полей. Таким образом, каждый раз, когда метод выполняется, он создает новые переменные, которые не используются совместно с другими выполнениями.

Scott Hannen 28.05.2019 03:25

по какой причине эти значения хранятся в экземпляре - вы хотите использовать их повторно или что-то еще?

vladimir 28.05.2019 04:52

@ScottHannen это то, что я предположил, должно быть так, но я думал, что каждый http-запрос будет создавать свой собственный объект XYZProxyhandler. Разве здесь не так? Любая ссылка на место, которая объясняет это?

user3754372 04.06.2019 00:50

Информация о том, когда они создаются, не отображается. Но поведение, которое вы описываете - это происходит время от времени, непоследовательно - является явным признаком проблемы параллелизма.

Scott Hannen 04.06.2019 01:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
274
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Я бы избавился от любых локальных переменных и передал бы требуемые значения напрямую:

public sealed class XYZProxyHandler : DelegatingHandler
{
   // If needed some thread-safe service, repo, etc can be passed in the constructor.
    /*
    private readonly ISmth _smth;

    public XYZProxyHandler(ISmth smth) 
    {
        _smth = smth;
    }
    */

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var token = request.Headers.GetCookies().FirstOrDefault().Cookies.FirstOrDefault(x => x.Name.ToLower() == "access_token").Value;
        var _var1 = GetVar1(token);
        var _var2 = GetVar2(token);

        SomeMethod(_var1, _var2);

        // ..
    }

    private void SomeMethod(string one, string two) {


    }
}  

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

user3754372 04.06.2019 00:55

Просто посмотрите на регистрация обработчика — он создается только один раз, а метод WebApiConfig.Регистрация вызывается при инициализации HTTP-приложение.

vladimir 04.06.2019 01:56

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

user3754372 04.06.2019 02:31

Другие вопросы по теме