我在Blazor页面中添加了一个计时器,因此某些数据(从数据库中提取)可以每5秒刷新一次。当我在页面上时,它工作正常,但是当我移至另一页面并返回原始页面时,出现此错误:


  “此连接用于环境交易。原始交易
  必须先完成环境交易,然后才能进行此连接
  在它之外使用”我在最后包括了堆栈跟踪


当页面被处置时,我尝试处置了Timer,但是它没有解决它。看来此问题是由于如何在依赖注入容器中注册数据库上下文而引起的,但是

这是我页面的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 Message =此
  连接用于环境事务。原始环境
  必须先完成交易,然后才能使用此连接
  在它外面。源= 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(Task
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)在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(Task
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)在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(Task
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)在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(Task
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)
  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(Task
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)
  System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1.ConfiguredTaskAwaiter.GetResult() at System.Linq.AsyncEnumerable.AsyncIterator 1.d__10.MoveNext()
  在
  D:\ a \ 1 \ s \ Ix.NET \ Source \ System.Interactive.Async \ AsyncIterator.cs:line
  112点
  System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在
  System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务),位于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(Task
  任务),位于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(任务
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)在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:line 91 at
  System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在
  System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
  任务)
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务),位于System.Runtime.CompilerServices.TaskAwaiter.GetResult()
  在
  TWMBlazorSSB.Pages.TaskApp.TaskApps。 d.MoveNext()
  在C:\ TFS [...] \ TaskApps.razor:第79行


任何帮助,将不胜感激。
谢谢

最佳答案

看来此问题是由于如何注册数据库上下文


那是正确的。这是因为AddDbContext<>使用(默认情况下)ServiceLifetime.Scoped。但是没有有用的范围。

这仍然是under discussion by the Blazor team,可能需要等待下一个预览,然后再考虑解决方法。

但我看到它现在撞到了Preview-9。

10-04 11:37
查看更多