C# .NET核心MVC,即使设置为瞬态,数据也会保持冻结
起初我认为这个问题是由单例引起的,但即使我的依赖项也设置为瞬态,我也有这个问题。我的代码所做的就是读取csv文件并将其映射到对象,如图所示:C# .NET核心MVC,即使设置为瞬态,数据也会保持冻结,c#,asp.net-core,dependency-injection,asp.net-core-mvc,C#,Asp.net Core,Dependency Injection,Asp.net Core Mvc,起初我认为这个问题是由单例引起的,但即使我的依赖项也设置为瞬态,我也有这个问题。我的代码所做的就是读取csv文件并将其映射到对象,如图所示: public class CallStatReports { string homeServer = @"\\10.XX.XX.XXX\Reports"; string csvName = "helpdeskCallStats.csv"; private int attempts; public CallStats T
public class CallStatReports
{
string homeServer = @"\\10.XX.XX.XXX\Reports";
string csvName = "helpdeskCallStats.csv";
private int attempts;
public CallStats TennesseeCallStats { get; set; }
public CallStats FloridaCallStats { get; set; }
public CallStats CorporateCallStats { get; set; }
public CallStats CRCCallStats { get; set; }
public void RefreshStats()
{
var filePath = Path.Combine(homeServer, csvName);
using (var fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new StreamReader(fileReader))
{
var cReader = new CsvReader(reader);
cReader.Configuration.Delimiter = ":";
cReader.Configuration.ReadingExceptionOccurred = null;
cReader.Configuration.RegisterClassMap<CallStatsMapper>();
var results = cReader.GetRecords<CallStats>().ToArray();
//Sometimes the stream will be empty, so this recursively calls itself until it hits 20 attempts and then returns
if (results.Count() == 0 && attempts++ <= 20)
{
Thread.Sleep(5);
RefreshStats();
return;
}
TennesseeCallStats = results.FirstOrDefault(x => x.SplitSkill == "Tenn E Emergent");
FloridaCallStats = results.FirstOrDefault(x => x.SplitSkill == "FL Emergent");
CorporateCallStats = results.FirstOrDefault(x => x.SplitSkill == "s_68_Corp Users");
CRCCallStats = results.FirstOrDefault(x => x.SplitSkill == "s_1 Help Desk");
}
}
}
}
public class CallStats
{
public CallStats()
{
SplitSkill = string.Empty;
SkillState = string.Empty;
AgentsStaffed = default(int);
CallsWaiting = default(int);
OldestCallWaiting = default(TimeSpan);
ACDCalls = default(int);
AvgACDTime = default(TimeSpan);
AbanCalls = default(int);
AvgAbanTime = default(TimeSpan);
AvgSpeedAns = default(TimeSpan);
}
public string SplitSkill { get; set; }
public string SkillState { get; set; }
public int AgentsStaffed { get; set; }
public int CallsWaiting { get; set; }
public TimeSpan OldestCallWaiting { get; set; }
public int ACDCalls { get; set; }
public TimeSpan AvgACDTime { get; set; }
public int AbanCalls { get; set; }
public TimeSpan AvgAbanTime { get; set; }
public TimeSpan AvgSpeedAns { get; set; }
}
public class AgentReports
{
string homeServer = @"\\10.XX.XX.XXX\Reports";
string csvName = "helpdesk.csv";
private int attempts;
public List<Agent> CorporateAgents
{
get;
set;
}
public List<Agent> CRCAgents
{
get;
set;
}
public List<Agent> TennesseeAgents
{
get;
set;
}
public List<Agent> FloridaAgents
{
get;
set;
}
public void RefreshStats()
{
var filePath = Path.Combine(homeServer, csvName);
using (var fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new StreamReader(fileReader))
{
var cReader = new CsvReader(reader);
cReader.Configuration.Delimiter = ":";
cReader.Configuration.ReadingExceptionOccurred = null;
var results = cReader.GetRecords<dynamic>().ToList();
//Sometimes the stream returns no data, so it recursively calls itself unless the stream was empty 20 times in a row.
if(results.Count == 0 && attempts++ <= 20)
{
Thread.Sleep(5);
RefreshStats();
return;
}
var convertedAgents = results.Select(x => new Agent()
{
AgentName = x.AgentName,
Icon = int.Parse(x.Icon),
State = x.State,
AuxReason = x.AuxReason,
Skills = new List<string>(((ExpandoObject)x).Where(y => y.Key.ToLower().Contains("skill")).Select(z => z.Value.ToString())),
LoginID = x.LoginID,
Time = TimeSpan.FromSeconds(double.Parse(x.Time))
}).ToList();
TennesseeAgents = convertedAgents.Where(x => x.Skills.Contains("Tenn E Emergent")).Distinct().ToList();
FloridaAgents = convertedAgents.Where(x => x.Skills.Contains("FL Emergent")).Distinct().ToList();
CRCAgents = convertedAgents.Where(x => x.Skills.Contains("s_1 Help Desk")).Distinct().ToList();
CorporateAgents = convertedAgents.Where(x => x.Skills.Contains("s_68_Corp Users")).Distinct().ToList();
}
}
}
页面可以通过jquery自己进行良好的更新(视图每隔3秒以setInterval刷新一次),但随着时间的推移,当加载数据时,网站最终会遇到内部服务器错误500
一旦出错,数据就会冻结。
CallStatReports对象只是一次又一次地重复自己,没有更新。这几乎就像是在使用同一个对象,即使它在从容器解析时被标记为瞬态
我一辈子都搞不懂为什么会发生这种事。
当运行调试器时,调试器不会在代码返回错误500的部分中断。我能够解决这个问题,我希望没有其他人需要经历我在过去一周中试图解决这个问题的地狱 显然,如果您正在从共享驱动器读取数据,Windows会以某种方式缓存数据。我能够通过每秒打开200次流来复制这个bug 几秒钟后,即使文件已更新,流也会以缓存数据打开。只有当您碰巧有一个很少更改的文件时,它才会这样做(就像在我的例子中,调用的数量会慢慢更新) 因为我可以在几秒钟而不是几小时内复制这个bug。。。我尝试了很多东西。在我决定将数据放在本地机器上,而不是试图从共享驱动器远程获取数据之前,一切似乎都不起作用 那立刻修复了错误 因此,为了简单地解释我是如何修复的,我基本上反转了数据导出。 我将导出配置为直接将数据导出到以前通过共享驱动器导入的服务器,而不是让服务器查询共享驱动器中的数据
我不是Windows专家,可能还有另一种方法来解决这个问题,比如清除共享驱动器缓存。。。但这对我很有效。首先将所有异常写入日志。然后您可以在没有断点的情况下检查它们。我建议您向该日志发送完整的异常以及所有关于导致异常的请求的数据。为什么您的工厂在构造函数中只使用一次?如果不将其用作工厂,则可以只注入两个报告。也就是说,如果DI代码来自DI容器,请发布DI代码。请同时发布DI配置。
public class DashboardController : Controller
{
private DashboardFactory _dashFactory;
public DashboardController(DashboardFactory dashFactory)
{
_dashFactory = dashFactory;
_dashFactory.AgentReports.RefreshStats();
_dashFactory.CallStatReports.RefreshStats();
}
public IActionResult Index()
{
return View(_dashFactory);
}
public IActionResult TNAgentView()
{
return PartialView("DashView",_dashFactory.TennesseeAgents);
}
public IActionResult FLAgentView()
{
return PartialView("DashView",_dashFactory.FloridaAgents);
}
public IActionResult CorpAgentView()
{
return PartialView("DashView",_dashFactory.Corporate);
}
public IActionResult CRCAgentView()
{
return PartialView("DashView",_dashFactory.CRC);
}
public IActionResult CRC()
{
return View(_dashFactory.CRC);
}
public IActionResult Corporate()
{
return View(_dashFactory.Corporate);
}
public IActionResult AccessCenter()
{
return View(_dashFactory);
}
}
public class DashboardFactory
{
private const int delayTime = 3;
public DashboardFactory(AgentReports agentReports, CallStatReports callStatReports)
{
this.CallStatReports = callStatReports;
this.AgentReports = agentReports;
callStatReports.RefreshStats();
agentReports.RefreshStats();
}
public DashModel Corporate
{
get
{
return new DashModel(AgentReports.CorporateAgents, CallStatReports.CorporateCallStats);
}
}
public DashModel CRC
{
get
{
return new DashModel(AgentReports.CRCAgents, CallStatReports.CRCCallStats);
}
}
public DashModel FloridaAgents
{
get
{
return new DashModel(AgentReports.FloridaAgents, CallStatReports.FloridaCallStats);
}
}
public DashModel TennesseeAgents
{
get
{
return new DashModel(AgentReports.TennesseeAgents, CallStatReports.TennesseeCallStats);
}
}
public CallStatReports CallStatReports { get; }
public AgentReports AgentReports { get; }
}