timer - System.Threading.Timer:在此上下文中启动了第二个操作
问题描述
我在 .NET 5 上有控制台应用程序,它是 Discord Bot。在启动应用程序时,我遇到了这个问题:
System.InvalidOperationException:在前一个操作完成之前,在此上下文上启动了第二个操作。这通常是由不同的线程同时使用同一个 DbContext 实例引起的。有关如何避免 DbContext 线程问题的更多信息
这发生在 Timer
这是在构造函数中:
_approveTimer = new Timer(async delegate
{
await CheckApproveAsync();
}, null, TimeSpan.Zero,
TimeSpan.FromSeconds(30));
public async Task CheckApproveAsync()
{
var pendingUsers = await _pendingUsers.GetAllAsync();
if (pendingUsers is null || !pendingUsers.Any())
return;
Program.Log.Debug($"Checking {pendingUsers.Count} pending users...");
foreach (var user in pendingUsers)
{
var expired = DateTime.UtcNow > user.ExpirationTime;
if (!expired) continue;
await _pendingUsers.DeleteWithDetachAsync(user);
IonicHelper.GetGuildUserById(_mainGuildId, user.UserId, out var sgUser);
try
{
var msg = await _messageService.GetMessageAsync("register-pending-expired", new FormatData(user.UserId));
await sgUser.SendIonicMessageAsync(msg);
}
catch (Exception ex)
{
await _serverHelper.SendLogAsync(_mainGuildId, "Error", $"{nameof(CheckApproveAsync)} - {ex.Message}");
}
}
var usersValidated = 0;
foreach (var user in pendingUsers)
{
RequestResult codeResult;
string code;
try
{
(codeResult, code) = await GetThirdPartyCodeByEncryptedSummonerIdAsync(user.Region, user.SummonerId);
}
catch (Exception)
{
continue;
}
if (code is null || codeResult != RequestResult.Success)
continue;
var sanitizedCode = new string(code.Where(char.IsLetterOrDigit).ToArray());
if (sanitizedCode != user.ConfirmationCode)
continue;
var (requestResult, summoner) = await GetSummonerByEncryptedPuuIdAsync(user.Region, user.PlayerUUID);
if (requestResult != RequestResult.Success)
{
await _pendingUsers.DeleteWithDetachAsync(user);
continue;
}
var (rankResult, rankData) = await GetLeaguePositionsByEncryptedSummonerIdAsync(user.Region, summoner.Id);
var soloqRank = GetRankModelFromEntry(rankData.FirstOrDefault(x => x.QueueType == "RANKED_SOLO_5x5"));
var summonerIcon = GetSummonerIconUrlById(summoner.ProfileIconId);
var lolData = new LeagueData
{
UserId = user.UserId,
SummonerRegion = user.Region,
PlayerUUID = summoner.Puuid,
AccountId = summoner.AccountId,
SummonerId = summoner.Id,
SummonerName = summoner.Name,
SummonerIcon = summonerIcon,
SummonerLevel = summoner.SummonerLevel,
SummonerRank = $"{soloqRank.Tier} {soloqRank.Rank}"
};
_ = IonicHelper.GetGuildUserById(_mainGuildId, user.UserId, out var sgUser);
await AssignRoleFromRankAsync(sgUser, soloqRank.Tier);
var data = await _leagueRepository.GetByIdAsync(user.UserId);
if (data == null)
{
await _leagueRepository.AddAsync(lolData);
}
usersValidated++;
user.SummonerName = lolData.SummonerName;
await PostValidateAsync(user);
}
Program.Log.Information($"{usersValidated} users validated.");
}
我读到如果不等待某些方法可能是个问题,但我已经检查过它是否都在等待。对此有何建议?
解决方案
推荐阅读
- python-3.x - 我在我的 python 脚本中遇到了一个 raise key 错误。我该如何解决这个问题?
- javascript - 删除两个字符串中的文本
- python - Python/paho MQTT - 不接收消息
- arrays - 关于数组的数据结构问题 - 如何在给定条件下找到最好的数组
- c++ - 获取 std::optional 包含的类型的最佳方法是什么?
- python - 如何使用带有可选第一个参数的输入提示
- r - 如何使用 Python 创建时间戳数据的流程图
- reactjs - 使用浏览器控制台,如何判断一个站点是使用 Next.js 还是 Create React Rpp
- sql - 有没有办法对记录进行排名?
- mysql - 如何查询某个时间窗口内访问过数据库的用户?