1

我每分钟都在运行一个托管服务。该服务将数据存储在缓存中的表中,然后使用数据并发送邮件。然后它删除记录。我必须这样做,因为如果发送邮件失败,我可以用相同的记录重试。

所以服务从缓存中获取数据。将其存储在表中。它从表中获取数据并发送邮件。成功时,它会从表中删除记录。但是,一分钟后,邮件被第二次发送了。如此接缝,记录不会第一次被删除。

我正在做这样的事情(缩短代码):

// my hostedservice class
public Task StartAsync(CancellationToken cancellationToken)
{
     // start timer
     _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(_timeout));
     return Task.CompletedTask;
}

private void DoWork(object state)
{
     using var scope = _serviceScopeFactory.CreateScope();
     ICacheService cacheService = scope.ServiceProvider.GetService<ICacheService>();
     IMailService mailService = scope.ServiceProvider.GetService<IMailService>();
     // transfer mails from cache
     for(...) {
          mailRepo.CreateMail(tmpMails[i]).GetAwaiter().GetResult();
          // cache gets cleared successfully, transfer is done only one time
     }
     // send mails
     List<Mail> mails = mailRepo.GetMailsForSend().GetAwaiter().GetResult();
     for(...) {
          // send mail
          // this one seems to work only on second time
          mailRepo.DeleteMail(mail).GetAwaiter().GetResult();
     }
}
// mailRepo
public async Task<bool> CreateMail(Mail mail)
{
     Add(mail);
     await _context.SaveChangesAsync();
     return true;
}
public async Task<bool> DeleteMail(Mail mail)
{
     Delete(mail);
     await _context.SaveChangesAsync();
     return true;
}
public async Task<List<Mail>> GetMailsForSend()
{
     return await _context.Set<Mail>().Where(m => m.NextTry<=DateTime.Now).ToListAsync();
}
// base functions, just for completion
public virtual void Add(T entity)
        {
            EntityEntry dbEntityEntry = _context.Entry<T>(entity);
            _context.Set<T>().Add(entity);
        }
public virtual void Delete(T entity)
        {
            EntityEntry dbEntityEntry = _context.Entry<T>(entity);
            dbEntityEntry.State = EntityState.Deleted;
        }

请给我一个提示,我可以如何改进我的代码,或者可能是什么原因。

更新 02.06.2020

我发现使用分离的范围时一切都像预期的那样工作。

private void DoWork(object state)
{
     using(var scope = _serviceScopeFactory.CreateScope()) {
        ICacheService cacheService = scope.ServiceProvider.GetService<ICacheService>();
        IMailService mailService = scope.ServiceProvider.GetService<IMailService>();
        // transfer mails from cache
        for(...) {
            mailRepo.CreateMail(tmpMails[i]).GetAwaiter().GetResult();
            // cache gets cleared successfully, transfer is done only one time
        }
     }
     using(var scope = _serviceScopeFactory.CreateScope()) {
        IMailService mailService = scope.ServiceProvider.GetService<IMailService>();
         // send mails
         List<Mail> mails = mailRepo.GetMailsForSend().GetAwaiter().GetResult();
         for(...) {
              // send mail
              // gets deleted on first run now
              mailRepo.DeleteMail(mail).GetAwaiter().GetResult();
         }
    }
}

在同一范围内创建和直接删除数据可能是问题吗?

谢谢!

4

0 回答 0