EF Core调用EntityState.已修改,然后发出异步http请求处理数据库上下文



导致问题的代码

var cats= await _animaldb.Cats.ToListAsync<Cats>();
foreach (var kitty in cats)
{
kitty.LastReq = DateTime.Now;
kitty.DailyReqCount = cats.DailyReqCount + 1;
// make HTTP request here to some endpoint async
var data = await _restOps.GetJsonAsync("url");
// perhaps thread is being disposed ?
_animaldb.Entry(kitty).State = EntityState.Modified;// err 2nd iteration 
}
_animaldb.SaveChanges();

db上下文被添加到startup.cs

services.AddDbContext<AnimalDBContext>(options => options.UseSqlServer(connection));

编辑:添加getJsonAsyn

public class RestOps
{
private readonly ILogger<RestOps> _logger;
private readonly Animaldb _animaldb;
public RestOps(ILogger<RestOps> logger, Animaldb animaldb)
{
_logger = logger;
_animaldb= animaldb;
}
public async Task<string> GetJsonAsync(string url, bool randomUserAgent = false)
{
var httpClientHandler = new HttpClientHandler();
var client = new HttpClient(httpClientHandler);
client.Timeout = TimeSpan.FromMilliseconds(3000);
UserAgents userAgent = await GetRndUserAgent();
var userAgentStr = string.Empty;
var resultUserAgent = randomUserAgent ? userAgentStr = userAgent.Name : userAgentStr = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36";
client.DefaultRequestHeaders.Add("User-Agent", resultUserAgent);
// Make a list of web addresses.  
// GetAsync returns a Task<HttpResponseMessage>. 
string content = null;
try
{
HttpResponseMessage response = await client.GetAsync(url);
// Retrieve the website contents from the HttpResponseMessage.  
content = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
content = "Failed to get:" + url;
}
return content;
}
private async Task<UserAgents> GetRndUserAgent()
{
UserAgents userAgent = null;
Random r = new Random();
var id = r.Next(0, 40);
using (_animaldb)
{
userAgent = await _animaldb.UserAgents.FindAsync(id);
}
return userAgent;
}
}

错误消息:

Cannot access a disposed object. A common cause of this error is disposing a 
context that was resolved from dependency injection and then later trying to 
use the same context instance elsewhere in your application. This may occur 
if you are calling Dispose() on the context, or wrapping the context in a 
using statement. If you are using dependency injection, you should let the 
dependency injection container take care of disposing context instances

注意:我在for循环中使用db上下文/修改并保存代码前面的条目ok!

编辑:我没有说我在做一个异步http请求,对不起!

TL;医生

这个问题似乎与线程被处理有关,我可以使用非异步http req,如果可能的话,我更希望能够保持这种方式,因为http请求需要一段时间才能完成。

谢谢你的帮忙,有什么想法吗?

删除GetRndUserAgent((中的usings语句,这是在处理数据库上下文!!!

using (_animaldb)
{
userAgent = await _animaldb.UserAgents.FindAsync(id);
}

最新更新