Я реализовал проект на .NET Core 2.2, который состоит из 1 консольного приложения и 1 библиотеки классов.Консольное приложение - это, по сути, потребитель, который подписывается на некоторые темы и обрабатывает поступающие сообщения. Библиотека классов - это слой базы данных, где у меня есть хранилище.Проблема заключается в том, что иногда я получаю сообщение об ошибке «System.InvalidOperationException: секундная операция, запущенная в этом контексте до завершения предыдущей операции. Любые члены экземпляра не гарантируют поточно-ориентированную защиту», когда происходит взаимодействие с базой данных.
Я искал похожие проблемы, но не мог найти решение, которое бы решило мою проблему.Я попытался зарегистрировать DbContext и IRepository как Scoped и Transient, но все еще продолжаю получать ошибку.Это неправильно, как я пытаюсь зарегистрировать DbContext?
Это мой код в Consumer.cs
class Consumer
{
static readonly IConfigurationRoot _configuration;
static readonly IServiceProvider _serviceProvider;
static readonly IRepository _repository;
static Consumer()
{
_configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
_serviceProvider = new ServiceCollection()
.AddSingleton(_configuration)
.AddTransient<IRepository, Repository>()
.AddDbContext<QueueContext>(options => options.UseNpgsql(_configuration.GetConnectionString("Queue")), ServiceLifetime.Transient)
.BuildServiceProvider();
_repository = _serviceProvider.GetService<IRepository>();
}
static void Main(string[] args)
{
...
RunPoll(here some parameters);
}
private static void RunPoll(here some parameters)
{
...
consumer.OnMessage += async (_, msg) => await ProcessMessageAsync(consumer, msg);
...
}
private static async Task ProcessMessageAsync(here some parameters)
{
...
var message = _repository.GetQueueMessage(msg.Value.Id); // On this line I get exception
if (message == null)
{
message = await _repository.AddQueueMessageAsync(msg.Value.Id); // On this line I get exception
}
while(message.NumTries < msg.Value.MaxNumAttempts)
{
message = await _repository.UpdateQueueMessageTriesAsync(message); // On this line I get exception too
}
...
}
}
Это мой код в Respository.cs
public class Repository : IRepository
{
private readonly QueueContext _db;
public Repository(QueueContext db)
{
_db = db;
}
public QueueMessage GetQueueMessage(long id)
{
var message = (from qm in _db.QueueMessages
where qm.Id == id
select qm).FirstOrDefault();
return message;
}
public async Task<QueueMessage> AddQueueMessageAsync(long id)
{
var message = new QueueMessage
{
Id = id,
StartDate = DateTime.Now,
LastTryDate = DateTime.Now,
NumTries = 0
}
_db.QueueMessages.Add(message);
await _db.SaveChangesAsync();
return message;
}
public async Task<QueueMessage> UpdateQueueMessageTriesAsync(QueueMessage message)
{
if (message != null)
{
message.NumTries += 1;
message.LastTryDate = DateTime.Now;
_db.QueueMessages.Update(message);
await _db.SaveChangesAsync();
}
return message;
}
}
Это мой код в IRepository.cs
public interface IRepository
{
QueueMessage GetQueueMessage(long id);
Task<QueueMessage> AddQueueMessageAsync(long id);
Task<QueueMessage> UpdateQueueMessageTriesAsync(QueueMessage message);
}