C # Blazor - Исправлено «Это соединение использовалось с внешней транзакцией ...» - PullRequest
3 голосов
/ 11 июля 2019

Я добавил таймер на страницу Blazor, чтобы некоторые данные (извлекаемые из базы данных) могли обновляться каждые 5 секунд. Он хорошо работает, когда я на странице, но когда я перехожу на другую страницу и возвращаюсь к исходной, я получаю эту ошибку:

"Это соединение использовалось с внешней транзакцией. Оригинал Перед этим соединение должно быть завершено. быть использованным вне этого "Я включил трассировку стека в конце

Я пытался избавиться от Таймера, когда страница удаляется, но это не помогло. Похоже, эта проблема связана с тем, как контекст БД зарегистрирован в контейнере внедрения зависимостей, но

Вот код C # моей страницы. Он вызывает основной сервис, который, в свою очередь, получает данные через репозиторий.

@functions {

    protected Dictionary<int, int> RunningTaskProcessQueueCountDictionary;
    protected Dictionary<int, int> PendingTaskProcessQueueCountDictionary;
    protected Timer CountRefreshTimer = null;

    protected override async Task OnInitAsync()
    {
        CountRefreshTimer = new Timer(new TimerCallback(async _ =>
        {
            await RefreshCount();
            await base.Invoke(StateHasChanged);
        }), null, 0, 5000);
    }


    private async Task RefreshCount()
    {
        RunningTaskProcessQueueCountDictionary = await mainService.GetRunningTaskProcessQueueCountByTaskAppAsync(null);
        PendingTaskProcessQueueCountDictionary = await mainService.GetPendingTaskProcessQueueCountByTaskAppAsync(null);
    }

    public void Dispose()
    {
        if (CountRefreshTimer != null)
        {
            CountRefreshTimer.Dispose();
        }
    }
}

Вот выдержка из файла startup.cs, в котором зарегистрирован контекст БД:

// Register the DB Context
var connection = Configuration.GetConnectionString("SQL01.xxx");
services.AddDbContext<SQL01xxxContext>(options => options.UseSqlServer(connection));

// Register all repositories and services (using Scrutor)
services.Scan(scan =>
    scan.FromAssemblies(typeof(IMainService).Assembly, typeof(ITaskAppRepository).Assembly)
        .AddClasses()
        .AsMatchingInterface()
        .WithScopedLifetime());

services.AddScoped<DbContext, SQL01xxxContext>();
services.AddScoped<IUnitOfWork<SQL01xxxContext>, UnitOfWork<SQL01xxxContext>>();

Это трассировка стека ошибки

System.InvalidOperationException HResult = 0x80131509 Сообщение = Это соединение было использовано с внешней транзакцией. Оригинальный эмбиент транзакция должна быть завершена, прежде чем это соединение может быть использовано вне этого. Источник = Microsoft.EntityFrameworkCore.Relational
StackTrace: в Microsoft.EntityFrameworkCore.Storage.RelationalConnection.HandleAmbientTransactions () в Microsoft.EntityFrameworkCore.Storage.RelationalConnection.d__42.MoveNext () в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable 1.AsyncEnumerator.d__12.MoveNext () в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.<ExecuteAsync>d__7 2.MoveNext () в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable 1.AsyncEnumerator.d__11.MoveNext () в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1.ConfiguredTaskAwaiter.GetResult() at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator 2.d__7.MoveNext () в D: \ a \ 1 \ s \ Ix.NET \ Source \ System.Interactive.Async \ Select.cs: строка 106 в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1.ConfiguredTaskAwaiter.GetResult() at System.Linq.AsyncEnumerable.AsyncIterator 1.d__10.MoveNext () в D: \ а \ 1 \ S \ Ix.NET \ Source \ System.Interactive.Async \ AsyncIterator.cs: линия 112 в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor 1.EnumeratorExceptionInterceptor.d__5.MoveNext () в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в System.Linq.AsyncEnumerable.d__6 3.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 120 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult () вSIQC.Enterprise.GenericRepository.Common.IQueryableExtensions.d__1 1.MoveNext() in C:\TFS\[...]\IQueryableExtensions.cs:line 28 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult () в SIQC.Enterprise.GenericRepository.RepositoryBase.ReadOnlyRepository 1.<GetAsync>d__12.MoveNext() in C:\TFS\[...]\ReadOnlyRepository.cs:line 174 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult () в ToolsWebManagementData.IntravexV21.Repository.TaskProcessQueueRepository.d__2.MoveNext () в C: \ TFS [...] \ TaskProcessQueueRepository.cs: строка 46 в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter 1.GetResult() at TWMBlazorSSB.Services.MainService.<GetRunningTaskProcessQueueCountByTaskAppAsync>d__21.MoveNext() in C:\TFS\[...]\MainService.cs:line 79 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult () в TWMBlazorSSB.Pages.TaskApp.TaskApps.d__7.MoveNext () в C: \ TFS [...] \ TaskApps.razor: строка 91 в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.GetResult ()
в TWMBlazorSSB.Pages.TaskApp.TaskApps. d.MoveNext () в C: \ TFS [...] \ TaskApps.razor: строка 79

Любая помощь будет принята с благодарностью. Спасибо

1 Ответ

0 голосов
/ 14 июля 2019

Похоже, что эта проблема связана с тем, как регистрируется контекст БД

Это правильно.Это связано с тем, что AddDbContext<> использует (по умолчанию) ServiceLifetime.Scoped.Но нет полезного Scope.

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

Но я вижу, что теперь оно поднято до предварительного просмотра-9,

...