我尝试创建一个具有 SQL 依赖项的工作服务,用于侦听表插入或更新事件。
我需要该应用程序在启动时运行任务,然后在插入和更新表事件上运行相同的任务。
任务,我需要在启动和表事件上运行
private async Task ProcessExchangeTask()
{
using (var scope = _serviceScopeFactory.CreateScope())
{
_commandDispatcher = scope.ServiceProvider.GetRequiredService<ICommandDispatcher>();
_queryDispatcher = scope.ServiceProvider.GetRequiredService<IQueryDispatcher>();
Exchange1C exchange = null;
do
{
exchange = await GetCurrentExchange(); // method return current entity (table row)
try
{
if (exchange != null)
{
// Incomes
if (exchange.ExchangeSourceTypeID == ExchangeSourceTypes.IncomeCreate)
{
await _commandDispatcher.HandleAsync(new IncomeCreateCommand(exchange));
continue;
}
...
// other commands
}
}
catch (Exception ex)
{
await _commandDispatcher.HandleAsync(new ExchangeErrorProcessCommand(exchange));
_logger.Log(LogLevel.Error, ex.StackTrace);
}
} while (exchange != null);
}
}
表事件处理程序
private void OnNotificationReceived(object sender, RecordChangedEventArgs<Exchange1C> e)
{
if (e.ChangeType == ChangeType.Insert || (e.ChangeType == ChangeType.Update && e.Entity.QueueStateID == 0))
{
Task.WhenAll(ProcessExchangeTask());
}
}
Worker.cs 的 ExecuteAsync 方法
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Table dependency init
string connection = "...";
var tableName = "Exchange1C";
var tableDependency = new SqlTableDependency<Exchange1C>(connection, tableName, "Queues");
tableDependency.OnChanged += OnNotificationReceived; // event listener
tableDependency.Start();
// Run task on worker service start. It need because maybe not processed rows in database when
// service start.
await ProcessExchangeTask();
}
问题:如果在ProcessExchangeTask运行时处理新表事件,会抛出以下异常:
<块引用>System.InvalidOperationException:在上一个操作完成之前,在此上下文中启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的。
在 Program.cs 中初始化 EF DbContext,然后注入命令处理程序。
services.AddDbContext<DbContext>(options => options.UseSqlServer(...));