I've a problem when I use Pararrel function in aspnetcore, in particular when in the cycle i try to save something in database. I get my data from externarl api and deseserialize it in my class. This is the Parallel code.
Root players = JsonConvert.DeserializeObject<Root>(responseStream);
var bulkhead = Policy.BulkheadAsync(10, Int32.MaxValue);
var tasks = new List<Task>();
foreach (var player in players.players)
{
var t = bulkhead.ExecuteAsync(async () =>
{
int wyId = Convert.ToInt32(player.wyId);
HttpRequestMessage secondRequest = createRequest("https://apirest.com/v2/players/" + wyId + "?details=currentTeam&imageDataURL=true");
var client2 = _clientFactory.CreateClient();
var response2 = await client2.SendAsync(secondRequest);
if (response2.IsSuccessStatusCode)
{
var responseStream2 = await response2.Content.ReadAsStringAsync();
dynamic playerFullDetails = JsonConvert.DeserializeObject<dynamic>(responseStream2);
int wyId2 = Convert.ToInt32(playerFullDetails.wyId);
int marketValue = 0;
HttpRequestMessage tirthRequest = createRequest("https://apirest.com/v2/players/" + wyId2 + "/marketvalue");
var client3 = _clientFactory.CreateClient();
var response3 = await client3.SendAsync(tirthRequest);
if (response3.IsSuccessStatusCode)
{
var responseStream3 = await response3.Content.ReadAsStringAsync();
dynamic marketValueResponse = JsonConvert.DeserializeObject<dynamic>(responseStream3);
if (marketValueResponse.marketValue != 0)
{
marketValue = Convert.ToInt32(marketValueResponse.marketValue);
}
}
DateTime birthday = Convert.ToDateTime(playerFullDetails.birthDate);
int age = DateTime.Now.Year - birthday.Year;
Player finalPlayer = new Player();
finalPlayer.PlayerId = wyId2;
finalPlayer.MarketValue = marketValue;
finalPlayer.Value = Convert.ToDouble(marketValue) / Convert.ToDouble(1000000);
finalPlayer.Firstname = playerFullDetails.firstName;
finalPlayer.Lastname = playerFullDetails.lastName;
finalPlayer.Name = playerFullDetails.shortName;
finalPlayer.Position = playerFullDetails.role.name;
finalPlayer.Height = playerFullDetails.height;
finalPlayer.Foot = playerFullDetails.foot;
finalPlayer.IsLocked = false;
finalPlayer.Team = playerFullDetails.currentTeam != null ? playerFullDetails.currentTeam.name : "";
finalPlayer.TeamId = playerFullDetails.currentTeam != null ? playerFullDetails.currentTeam.wyId : 0;
finalPlayer.CompetitionId = 524;
finalPlayer.UpdatedDay = DateTime.Now;
finalPlayer.League = "Serie A";
finalPlayer.Age = age;
Player playerExist = await _context.Player.Where(x => x.PlayerId == wyId2).SingleOrDefaultAsync();
if (playerExist == null)
{
if (finalPlayer.TeamId != 0)
{
await _context.Player.AddAsync(finalPlayer);
await _context.SaveChangesAsync();
}
}
if (finalPlayer.TeamId != 0)
{
Team teamExist = await _context.Team.Where(x => x.TeamId == finalPlayer.TeamId).SingleOrDefaultAsync();
if (teamExist == null)
{
Team team = new Team();
team.TeamId = finalPlayer.TeamId;
team.TeamName = finalPlayer.Team;
await _context.Team.AddAsync(team);
await _context.SaveChangesAsync();
}
}
}
});
tasks.Add(t);
}
await Task.WhenAll(tasks);
The function isert 50/60 (in total would be 500) element in db and finally i receive this error
A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
Thanks