C# Blazor - Fix “This connection was used with an ambient transaction…”
我在Blazor页面中添加了一个计时器,因此某些数据(从数据库中提取)可以每5秒刷新一次。 当我在页面上时,它工作正常,但是当我移至另一页面并返回原始页面时,出现此错误:
"This connection was used with an ambient transaction. The original
ambient transaction needs to be completed before this connection can
be used outside of it" I've included the stack trace at the end
当页面被处置时,我尝试处置了Timer,但是它没有解决它。 看来此问题是由于如何在依赖注入容器中注册数据库上下文而引起的,但是
这是我页面的C#代码。 它调用主服务,后者又通过存储库获取数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | @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的摘录:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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 Message=This
connection was used with an ambient transaction. The original ambient
transaction needs to be completed before this connection can be used
outside of it. Source=Microsoft.EntityFrameworkCore.Relational
StackTrace: at
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.HandleAmbientTransactions()
at
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.d__42.MoveNext()
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.TaskAwaiter1.GetResult() 1.AsyncEnumerator.d__12.MoveNext()
at
Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable
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.TaskAwaiter1.GetResult() 2.MoveNext()
at
Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.d__7
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.TaskAwaiter1.GetResult() 1.AsyncEnumerator.d__11.MoveNext()
at
Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable
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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() 2.d__7.MoveNext()
at
System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator
in D:\\a\\1\\s\\Ix.NET\\Source\\System.Interactive.Async\\Select.cs:line 106
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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() 1.d__10.MoveNext()
at
System.Linq.AsyncEnumerable.AsyncIterator
in
D:\\a\\1\\s\\Ix.NET\\Source\\System.Interactive.Async\\AsyncIterator.cs:line
112 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.TaskAwaiter1.GetResult() 1.EnumeratorExceptionInterceptor.d__5.MoveNext()
at
Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at System.Linq.AsyncEnumerable.d__63.MoveNext() 1.GetResult()
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
at
SIQC.Enterprise.GenericRepository.Common.IQueryableExtensions.d__11.MoveNext() 1.GetResult()
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
at
SIQC.Enterprise.GenericRepository.RepositoryBase.ReadOnlyRepository1. 1.GetResult()d__12.MoveNext()
in C:\\TFS\\[...]\
eadOnlyRepository.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
at
ToolsWebManagementData.IntravexV21.Repository.TaskProcessQueueRepository.d__2.MoveNext()
in C:\\TFS[...]\\TaskProcessQueueRepository.cs:line 46 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.TaskAwaiter1.GetResult() 1.GetResult()
at
TWMBlazorSSB.Services.MainService.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
at TWMBlazorSSB.Pages.TaskApp.TaskApps.d__7.MoveNext()
in C:\\TFS[...]\\TaskApps.razor:line 91 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.GetResult()
at
TWMBlazorSSB.Pages.TaskApp.TaskApps.d.MoveNext()
in C:\\TFS[...]\\TaskApps.razor:line 79
任何帮助,将不胜感激。
谢谢
It looks like this issue is due to how the DB context is registered
那是正确的。 这是因为
Blazor团队仍在讨论这一问题,也许在考虑下一种解决方法之前,请等待下一个预览。
但我看到它现在撞到了Preview-9。