gpt4 book ai didi

c# - asp.net core dbcontext 在计时器结束时被释放

转载 作者:太空宇宙 更新时间:2023-11-03 12:17:26 25 4
gpt4 key购买 nike

我的 asp.net 应用程序有问题。

我的应用程序应该每天对网站进行一次网络抓取。

我正在尝试使用计时器触发一个方法,而我正在尝试处理的这个方法需要我的 dbcontext 来保存新数据。

如果我运行我的应用程序并转到根据请求调用此方法的页面,我的方法工作正常,但是当计时器尝试使用它时,我的 dbcontext 被释放。

我的问题是.. 我如何配置我的 asp.net 应用程序以便我可以在后台重用我的 dbcontext 而不是依赖于来自网络浏览器的请求?

这是一些代码:

启动.cs

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; } }
}

FundDataService.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();
}
}
}
}

最佳答案

我认为最好的方法是在每个耗时实例化上下文,注入(inject) DbContextOptions<FundContext>而不是 FundContextFundDataService构造函数并执行 using/new 以更好地控制:

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
...

using(var context = new FundContext(_options)){
GetFundFromWebAndSavetoDB(context);
PopulateFundLists(context);
}

...
}

关于c# - asp.net core dbcontext 在计时器结束时被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49074417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com