场景如下:具有多个线程的应用程序:2用于请求来自不同源的数据,3用于更新屏幕上的不同信息,1用于按需播放音频。 问题是:应用程序必须不停地工作,并且在启动时工作正常,但过了一会儿(并不总是相同,通常在5到8小时之间),它最终会失败。错误跟踪点 到其中一个绘制线程,我得到异常“System.OutOfMemoryException”5或6分钟,直到最后程序停止。该线程在另外两个内部运行,这两个动画是在更新信息之前和之后持续1秒的2个动画(fadeIn,fadeOut)。如果我删除这些动画,程序不会失败(至少24小时)。我想保留动画,并帮助检测我做错了什么,我想我不会释放资源或类似的东西。
我看了两件事:
1)应用程序内存:我创建了这个变量
PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes");"
并在每个线程传递中我以这种方式执行:
"RAM disponible: " + ramCounter.NextValue() + "MB"
该值始终在3.5 / 4Gb左右,因此它似乎没有丢失内存。
2)线程数:我读到应用程序可以创建的线程数有限制,我认为如果我没有正确关闭它们可能就是问题所在。但它似乎也没有。我在每个线程传递上执行它,它总是给我一个30到35之间的稳定值:
"NumThreads: "+System.Diagnostics.Process.GetCurrentProcess().Threads.Count"
我附上了代码,看看你能否告诉我我做错了什么:
绘制信息的线程(如果我删除动画的行,应用程序可以正常工作)
while (true){
try{
EscribirLogError("PintarTiempos - RAM disponible: " + ramCounter.NextValue() + "MB",false);
tiempoPrevisiones = int.Parse(ConfigurationManager.AppSettings["TIEMPOPREVS"]);
//Animación quitar tiempos
tFadeOut = new Thread(new ThreadStart(FadeOut));
tFadeOut.SetApartmentState(ApartmentState.STA);
tFadeOut.Start();
//Pintar tiempos
this.window.pintaTiempos(previsiones);
Console.WriteLine("NumThreads: " + System.Diagnostics.Process.GetCurrentProcess().Threads.Count);
EscribirLogError("NumThreads: "+System.Diagnostics.Process.GetCurrentProcess().Threads.Count,false);
//Animación tiempos nuevos
tFadeIn = new Thread(new ThreadStart(FadeIn));
tFadeIn.SetApartmentState(ApartmentState.STA);
tFadeIn.Start();
Thread.Sleep(tiempoPrevisiones * 1000);
}catch(Exception e){
EscribirLogError("PintaTiempos:" + e.Message, true);
}
public void FadeIn()
{
TimeSpan fadeInTime = TimeSpan.Parse("00:00:01");
Double opacityFinalFadeIn = 1d;
Thread.Sleep(750);
this.window.FadeIn(fadeInTime, opacityFinalFadeIn);
}`
来自实例this.window
的fadeIn函数public void FadeIn(TimeSpan fadeInTime, Double d)
{
this.Dispatcher.Invoke(new System.Action(() =>
{
try
{
var fadeInAnimation = new DoubleAnimation(1d, fadeInTime);
for (int i = 0; i < this.lblTiempos.Length; i++)
{
this.lblLineas[i].BeginAnimation(Label.OpacityProperty, fadeInAnimation);
this.lblDestinos[i].BeginAnimation(Label.OpacityProperty, fadeInAnimation);
this.lblTiempos[i].BeginAnimation(Label.OpacityProperty, fadeInAnimation);
}
}
catch (Exception e)
{
this.programa.EscribirLogError("FadeIn.Dispatcher:" + e.Message, true);
}
}), null);
}
我根据用户@Kelly的要求提供了有关计时器和事件的信息:
//Timers definition
private System.Windows.Forms.Timer time;
private System.Windows.Forms.Timer wakeup;
//Timers init
this.wakeup = new System.Windows.Forms.Timer();
this.wakeup.Tick += new EventHandler(wakeup_Tick);
this.wakeup.Interval = 30000;
this.time = new System.Windows.Forms.Timer();
this.time.Tick += new EventHandler(time_Tick);
this.time.Interval = 1000;
//Timer functions
private void wakeup_Tick(object sender, EventArgs e){
SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
}
private void time_Tick(object sender, EventArgs e){
try{
this.window.setFechaHora(DateTime.Now.ToString("dd / MM / yyyy"), DateTime.Now.ToString("HH:mm"));
}catch (Exception ex){
EscribirLogError("time_Tick " + ex.Message,false);
}
}
//Window function
public void setFechaHora(String fecha, String hora){
this.lblFecha.Content = fecha;
this.lblHora.Content = hora;
}
答案 0 :(得分:2)
您发布的信息不足以帮助解决此问题。内存分析器是您所需要的。我对Redgate ANTS祝你好运。
要注意的一些事项: