Либо мои словари разучились считать, либо у меня есть гонка, о которой я не знаю.C#

Место общения программистов C#
Ответить
Anonymous
 Либо мои словари разучились считать, либо у меня есть гонка, о которой я не знаю.

Сообщение Anonymous »

У нас есть устаревшее приложение, которое нам все еще необходимо поддерживать (.NET Framework 4.7.2), и мы недавно перенесли эти приложения на новый сервер из-за затрат или чего-то еще. Поскольку мы переместили приложения, большинство из них выдают «странные» ошибки, причем все где-то в районе конечной точки oauth.
  • Как я делаю DbSet.FirstOrDefault() и он выдает исключение IndexOutOfRangeException в Dictionary.Insert().
  • Или я пытаюсь получить доступ к ChangeTracker.Entries(), и он бросает с IndexOutOfRangeException в ObjectStateManager.GetObjectStateEntriesInternal()
  • Я вызываю DataContext.SaveChanges(), и он сообщает мне, что не может начать транзакцию, потому что один уже работает; или наоборот, для этой задачи нужна транзакция... Я ничего не делаю с транзакциями в этом месте.
  • Или свойство 'Id' является частью ключа объекта информацию и не может быть изменена., пока я добавляю новый объект в DbSet (без идентификатора, его создание будет задачей EF/DB).
Мой опыт работы с C# ограничен, а с .NET тем более. Я скорее интерфейсный разработчик, но, судя по тому, что я прочитал, все указывает на состояние гонки, когда изменяется DataContext; Я просто не знаю, кто/как/где.
Трассировка стека всегда выглядит так: oauth, oauth, oauth, затем какая-то конечная точка в одном из поставщиков токенов, а затем происходит сбой. в недрах EF

Код: Выделить всё

System.IndexOutOfRangeException: Der Index war außerhalb des Arraybereichs.
bei System.Data.Entity.Core.Objects.ObjectStateManager.GetObjectStateEntriesInternal(EntityState state)
bei System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)
bei System.Data.Entity.Infrastructure.DbChangeTracker.Entries()
bei MyNamespace.DAL.DataContext.SaveChanges() in ...
bei MyNamespace.OAuth.RefreshAuthenticationTokenProvider.Create(AuthenticationTokenCreateContext context) in ...
bei MyNamespace.OAuth.RefreshAuthenticationTokenProvider.CreateAsync(AuthenticationTokenCreateContext context) in ...
bei Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.d__8.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.d__7.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.d__7.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.d__12.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar)
bei System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
bei System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
bei System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Код этих поставщиков токенов мало что делает. Устанавливает старый токен как отключенный в базе данных и добавляет новую запись в базу данных.
Никаких потоков, ничего особенного.

Код: Выделить всё

// constructor contains only DI
// and there are two similar methods Receive/ReceiveAsync that crash identical to `Create`.
public class RefreshAuthenticationTokenProvider: Microsoft.Owin.Security.Infrastructure.IAuthenticationTokenProvider
{
private readonly IDataContext dataContext;

public void Create(AuthenticationTokenCreateContext context)
{
context.SetToken(context.SerializeTicket());

var userId = context.Ticket.Identity.Claims.First(item => item.Type == "sub" || item.Type == ClaimTypes.NameIdentifier).Value;

dataContext.OAuthRefreshTokens.Add(new OAuthRefreshToken
{
UserId = userId,
Disabled = false,
Token = context.Token,
ClientId = context.Ticket.Properties.RedirectUri,
Issued = context.Ticket.Properties.IssuedUtc?.LocalDateTime ?? DateTime.Now,
Expires = context.Ticket.Properties.ExpiresUtc?.LocalDateTime ?? DateTime.Now
});

var oldToken = dataContext.OAuthRefreshTokens.FirstOrDefault(item => item.UserId == userId && !item.Disabled);

if (oldToken != null)
{
oldToken.Disabled = true;
}

dataContext.SaveChanges();
}

public Task CreateAsync(AuthenticationTokenCreateContext context)
{
Create(context);

return Task.CompletedTask;
}
}

Код: Выделить всё

// this might be relevant:
container.RegisterType(
new PerRequestLifetimeManager(),
new InjectionConstructor("DataContext")
);

container.RegisterType(
"Transient_IDataContext",
new TransientLifetimeManager(),
new InjectionConstructor("DataContext")
);

app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = false,
ApplicationCanDisplayErrors = true,
TokenEndpointPath = new PathString("/OAuth/Token"),
AuthorizeEndpointPath = new PathString("/OAuth/Authorize"),
Provider = UnityConfig.Container.Resolve(),
AccessTokenFormat = UnityConfig.Container.Resolve(),
AuthorizationCodeProvider = UnityConfig.Container.Resolve(),
RefreshTokenProvider = UnityConfig.Container.Resolve(),

AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(
configurationManager.Get("OAuth.AccessToken.ExpireTimeSpan")
),
AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(
configurationManager.Get("OAuth.AuthorizationCode.ExpireTimeSpan")
)
});
Проблемы возникают только в реальных средах, даже не в одинаковых сценических средах (может быть, из-за объема трафика?)

И я не могу воспроизвести проблема вообще локальная.

И почему эти условия гонки не влияют на остальную часть приложения, а только на конечную точку oauth?
Как отладить такую ​​вещь?
Спасибо за всю помощь, которую я могу получить.

Подробнее здесь: https://stackoverflow.com/questions/792 ... -im-not-aw
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»