[英]When does a DbContext instance get disposed in ASP.NET Core 5
[英]asp.net core dbcontext is disposed when timer elapsed
我的 asp.net 应用程序有问题。
我的应用程序应该每天抓取一个网站一次。
我正在尝试使用计时器触发一个方法,我正在尝试处理的这个方法需要我的 dbcontext 来保存新数据。
如果我运行我的应用程序并转到根据请求调用此方法的页面,我的方法工作正常,但是当计时器尝试使用它时,我的 dbcontext 会被处理。
我的问题是.. 我如何配置我的 asp.net 应用程序,以便我可以在后台重用我的 dbcontext 而不依赖于来自 Web 浏览器的请求?
这是一些代码:
启动文件
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<FundContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("FundContext")));
services.AddTransient<IFundDataService, FundDataService>();
services.AddMvc();
}
FundContext.cs
public class FundContext : DbContext, IFundContext
{
public FundContext(DbContextOptions<FundContext> options)
: base(options)
{
}
public DbSet<Fund> Funds { get; set; }
}
FundsModel.cshtml.cs
public class FundsModel : PageModel
{
private IFundDataService fundDataService;
public FundsModel(IFundDataService fundDataService)
{
this.fundDataService = fundDataService;
}
public void OnGet()
{
}
public List<Fund> TodaysFundList { get { return fundDataService.TodaysFundList; } }
public List<Fund> YesterdaysFundList { get { return fundDataService.YesterdaysFundList; } }
}
基金数据服务.cs
public class FundDataService : Controller, IFundDataService
{
private FundContext fundContext;
private List<Fund> todaysFundList;
private List<Fund> yesterdaysFundList;
private static Timer timer;
public FundDataService(FundContext fundContext)
{
this.fundContext = fundContext;
GetFundFromWebAndSavetoDB();
PopulateFundLists();
InitializeTimer();
}
public List<Fund> TodaysFundList { get { return todaysFundList; } }
public List<Fund> YesterdaysFundList{ get { return yesterdaysFundList; } }
private void InitializeTimer()
{
DateTime timeNow = DateTime.Now;
DateTime scheduledTime = new DateTime(timeNow.Year, timeNow.Month, timeNow.Day, 00, 01, 00);
if(timeNow > scheduledTime)
{
scheduledTime = scheduledTime.AddDays(1);
}
double tickTime = 10000;/*(double)(scheduledTime - DateTime.Now).TotalMilliseconds;*/
timer = new Timer(tickTime);
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Stop();
GetFundFromWebAndSavetoDB();
PopulateFundLists();
InitializeTimer();
}
private void PopulateFundLists()
{
todaysFundList = new List<Fund>();
yesterdaysFundList = new List<Fund>();
foreach (var fund in fundContext.Funds)
{
if(fund.DateAddedToDB == DateTime.Now.Date)
{
todaysFundList.Add(new Fund
{
ID = fund.ID,
Name = fund.Name,
RateLastDay = fund.RateLastDay,
RateThisYear = fund.RateThisYear,
LastUpdate = fund.LastUpdate,
DateAddedToDB = fund.DateAddedToDB
});
}
if (fund.DateAddedToDB == DateTime.Now.Date.AddDays(-1))
{
yesterdaysFundList.Add(new Fund
{
ID = fund.ID,
Name = fund.Name,
RateLastDay = fund.RateLastDay,
RateThisYear = fund.RateThisYear,
LastUpdate = fund.LastUpdate,
DateAddedToDB = fund.DateAddedToDB
});
}
}
todaysFundList.Sort(delegate (Fund a, Fund b)
{
return b.RateThisYear.CompareTo(a.RateThisYear);
});
yesterdaysFundList.Sort(delegate (Fund a, Fund b)
{
return b.RateThisYear.CompareTo(a.RateThisYear);
});
}
private void GetFundFromWebAndSavetoDB()
{
var rawData = WebScrapingService.Instance.WebScrapeSiteAndReturnCollection(
"url"
, "//tbody/tr");
foreach (var fund in rawData)
{
decimal rateLastDay;
bool rateLastDayOK = decimal.TryParse(fund.ChildNodes[5].InnerText, out rateLastDay);
decimal rateThisYear;
bool rateThisYearOK = decimal.TryParse(fund.ChildNodes[11].InnerText, out rateThisYear);
var newFund = new Fund
{
Name = fund.ChildNodes[3].InnerText,
RateLastDay = rateLastDay,
RateThisYear = rateThisYear,
LastUpdate = Convert.ToDateTime(fund.ChildNodes[21].InnerText),
DateAddedToDB = DateTime.Now.Date
};
var NumberOfFundsAddedToday = (from x in fundContext.Funds where x.DateAddedToDB == DateTime.Now.Date select x).Count();
if(NumberOfFundsAddedToday < 5)
{
fundContext.Funds.Add(newFund);
fundContext.SaveChanges();
}
}
}
}
我认为最好的形式给出的实例化上下文中的每个ellapsed时间,注入DbContextOptions<FundContext>
代替FundContext
在FundDataService
构造和更好的控制做一个使用/新:
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
...
using(var context = new FundContext(_options)){
GetFundFromWebAndSavetoDB(context);
PopulateFundLists(context);
}
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.