У нас реализован 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 раз в месяц, может быть, не очень часто.
Я не уверен, что у меня туннельное зрение и я не вижу чего-то очевидного или бросающегося в глаза.
по какой причине эти значения хранятся в экземпляре - вы хотите использовать их повторно или что-то еще?
@ScottHannen это то, что я предположил, должно быть так, но я думал, что каждый http-запрос будет создавать свой собственный объект XYZProxyhandler. Разве здесь не так? Любая ссылка на место, которая объясняет это?
Информация о том, когда они создаются, не отображается. Но поведение, которое вы описываете - это происходит время от времени, непоследовательно - является явным признаком проблемы параллелизма.





Экземпляр класса Делегирующий обработчик одновременно используется всеми запросами, которые получает приложение, поэтому такое поведение предсказуемо.
Я бы избавился от любых локальных переменных и передал бы требуемые значения напрямую:
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) {
}
}
Я предположил, что, поскольку это не статический класс, каждый запрос получит свой собственный объект обработчика, но похоже, что это не так, и все запросы используют один и тот же объект. Можете ли вы поделиться какой-нибудь ссылкой, где объясняется этот случай, поскольку кажется, что я что-то упустил в основной документации?
Просто посмотрите на регистрация обработчика — он создается только один раз, а метод WebApiConfig.Регистрация вызывается при инициализации HTTP-приложение.
У меня была такая же мысль, и я просто хотел подтвердить. Я только что проверил, поместив спящий режим между двумя переменными, и смог воспроизвести его. Таким образом, по сути, все запросы используют один и тот же объект обработчика.
Это означает, что несколько запросов совместно используют экземпляры этого непоточно-ориентированного класса. Регистрация его как зависимости с ограниченной областью должна исправить это. Или, если реальный код очень похож на этот, переместите объявления переменных в метод вместо использования полей. Таким образом, каждый раз, когда метод выполняется, он создает новые переменные, которые не используются совместно с другими выполнениями.