Foros del Web » Programación para mayores de 30 ;) » .NET »

Error Hashtable

Estas en el tema de Error Hashtable en el foro de .NET en Foros del Web. Buenas , estoy trabajando con hashtables con c#, la dinamica es la siguiente leer de un archivo, extraer informacion del mismo e ir guardandola en ...
  #1 (permalink)  
Antiguo 28/05/2008, 11:15
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Error Hashtable

Buenas , estoy trabajando con hashtables con c#, la dinamica es la siguiente leer de un archivo, extraer informacion del mismo e ir guardandola en una hashtable, el problema es que en cierto punto me da un error de Out Of Memory Exception, por lo que sospecho que el hashtable no tiene capacidad de almacenar mas datos, como podria solventar este problema les agradezco mucho su colaboracion.
  #2 (permalink)  
Antiguo 28/05/2008, 11:54
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

puedes poner tu codigo??
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #3 (permalink)  
Antiguo 28/05/2008, 12:01
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

El codigo es este

public List<Hashtable> leerCargaTxt(configuracion estrucTablas)
{
Singleton.Instance.progreso.PerformStep();
Singleton.Instance.resultados.Items.Add(DateTime.N ow + ": Lectura del Archivo de Carga " + estrucTablas.nombArchOrigen.ToString());
int numeroColumnas = estrucTablas.tipoAtr.Count; //Numero de columnas que hay en el archivo config
List<Hashtable> columnas = new List<Hashtable>();
for (int i = 0; i < numeroColumnas; i++) //Aqui se agregan el numero de HashTables que hay dentro de cada tabla (una por atributo)
{
columnas.Add(new Hashtable());
}
try
{
//Lectura de archivo de data
StreamReader lectCarga = new StreamReader(Singleton.Instance.rutaDataFuente.Tex t + "\\" + estrucTablas.nombArchOrigen);
string Linea = "";
int fila = 0;//Filas que se van recorriendo del archivo de lectura

Linea = lectCarga.ReadLine();

while (Linea != null)//Aqui se lee linea a linea el archivo donde viene la data para ser guardado en el vector lineas
{
//Creacion de Lista de Hashtables en el orden especificado con Will
string[] atributos = Linea.Split('|');


for (int columna = 0; columna < atributos.Length; columna++)
{
try
{
//valida el numero de columnas corresponda con el numero de atributos
if (atributos.Length > numeroColumnas) throw new ExceptionNumeroColumnas(fila, estrucTablas.nombArchOrigen.ToString());
//valida el largo de cada atributo corresponda con el largo de la configuracion
if (atributos[columna].Length > Convert.ToInt32(estrucTablas.tipoAtr[columna].tamano)) throw new ExceptionLongCampos(fila, columna, estrucTablas.nombArchOrigen.ToString());
//valida el tipo de dato
bool tipo = validaTipo(atributos[columna], estrucTablas.tipoAtr[columna].tipoAtr);
if (tipo == false) throw new ExceptionTipoAtributo(fila, columna, estrucTablas.nombArchOrigen.ToString());
else//Aqui se agregan las filas
{
if (columnas[columna].Contains(atributos[columna]))//Aqui se agrega la fila en la que se encuentra ese registro esto si el atributo ya esta cargado en el hash
{
List<int> posiciones = (List<int>)columnas[columna][atributos[columna]];
posiciones.Add(fila);
columnas[columna][atributos[columna]] = posiciones;

}
else//Aqui se agrega la fila en la que se encuentra ese registro y el valor del registro como tal esto si el atributo NO esta cargado en el hash
{
List<int> posiciones = new List<int>();
posiciones.Add(fila);
columnas[columna].Add(atributos[columna], posiciones);
}
}
}
catch (ExceptionLongCampos ex)
{
ControlInterfaz.log.Add(DateTime.Now + " : " + ex);
Singleton.Instance.resultados.Items.Add(" ERROR: por tanto NO se ha podido cargar el archivo " + estrucTablas.nombArchOrigen.ToString());
return null;
}
catch (ExceptionTipoAtributo ex)
{
ControlInterfaz.log.Add(DateTime.Now + " : " + ex);
Singleton.Instance.resultados.Items.Add(" ERROR: por tanto NO se ha podido cargar el archivo " + estrucTablas.nombArchOrigen.ToString());
return null;
}
catch (ExceptionNumeroColumnas ex)
{
ControlInterfaz.log.Add(DateTime.Now + " : " + ex);
Singleton.Instance.resultados.Items.Add(" ERROR: por tanto NO se ha podido cargar el archivo " + estrucTablas.nombArchOrigen.ToString());
return null;
}

}
fila++;
Linea = lectCarga.ReadLine();
}
estrucTablas.numRegis = fila;
lectCarga.Close();
}
catch (FileNotFoundException ex)
{
ControlInterfaz.log.Add(DateTime.Now + " : " + ex);
Singleton.Instance.resultados.Items.Add("ERROR : El archivo " + estrucTablas.nombArchOrigen.ToString() + " NO se pudo encontrar");
return null;
}
return columnas;
}


Aqui es donde leo el archivo y lo vacio dentro de cada hashtable incluida en el vector de columnas
  #4 (permalink)  
Antiguo 28/05/2008, 12:23
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

ok puedes hacer algo en donde haces

posicisiones.Add(fila)

lo q recomeindo q despues de hacer es

posiciones.Clear(); para liberar esa memoria por etapas

y trata de crear la menor cantidad de arrays nuevos si puedes hacer

columnas[columna][atributos[columna]].Add(fila) seria mejor porq evitas crear un List nuevo.
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #5 (permalink)  
Antiguo 28/05/2008, 12:52
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Pero estas seguro de que no me esta dando el error pq la hashtable llega al maximo de su capacidad? y te digo esto pq estoy trabajando en servidor de 12 GB de RAM
  #6 (permalink)  
Antiguo 28/05/2008, 13:15
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Hice lo que me indicaste con los vectores y lleno la tabla de hash con 15 millones de Keys pero ahora cuando voy a escribir dentro de este metodo

public void Escribir(FileStream archivo, Hashtable tabla)
{
try
{
Singleton.Instance.progreso.PerformStep();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(archivo, tabla);
}
finally
{
archivo.Close();
}
}

Me da el error de Out Of memory Exception, y cuando me coloco sobre la Hastable "Tabla" en vez de mostrarme los valores que tiene la hashtable dice " Function Evaluation disabled because a precious function evaluation timeout You must continue execution to reenable function execution"
  #7 (permalink)  
Antiguo 28/05/2008, 13:53
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

ok entonces es a la escritura , el detalle aqui q puede suceder es q al momento de serializar tu clase tabla este no tenga el atributo de serializable o uno de tus atributos dentro de tu clase q estas serializando (una propiedad) esta en un ciclo sin fin y provoca la excepcion.

puede sponer el codigo de tus clases q van dentro de tu hashtable q tienes con el atributo "serializable"
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #8 (permalink)  
Antiguo 28/05/2008, 14:03
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Nuevamente muchas Gracias por tu Ayuda Peter muy amable como siempre, la cuestion es la siguiente yo serializo una hashtable para almacenarla de forma binaria dentro de un archivo de texto, tengo ya meses haciendolo el problema me surgio ahora cuando trate trabajar con un archivo de 15 millones de lineas como archivo fuente es decir la tabla de hash ahorita tendra 15 millones de keys diferentes.

public void Escribir(FileStream archivo, Hashtable tabla)
{
try
{
Singleton.Instance.progreso.PerformStep();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(archivo, tabla);
}
finally
{
archivo.Close();
}
}

como te mencionaba anteriormente a este metodo llegan el nombre de un filestream donde se almacenara la tabla de forma binaria y la tabla de hash como tal.

La linea de

BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(archivo, tabla);

Deriva de la clase System.Runtime.Serialization.Formatters.Binary;

No entiendo entonces que puede estar ocurriendo
  #9 (permalink)  
Antiguo 28/05/2008, 14:09
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

donde esta la linea donde estas invocando a este metodo la linea exacta.

debes tener una linea

clase.Escribir(obj.archivom,obj.tabla)

si es asi

pon entonces las lineas donde defines obj.tabla (la propiedad)
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #10 (permalink)  
Antiguo 28/05/2008, 14:20
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

El codigo completo es el siguiente Peter

public void Escribir(FileStream archivo, Hashtable tabla)
{
try
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(archivo, tabla);
}
finally
{
archivo.Close();
}
}

public void EscrituraCarg(List<Hashtable> columnas, configuracion estrucTablas, int numTablas)
{
for (int descar = 0; descar < columnas.Count; descar++)
{
FileStream archColumn = new FileStream(Singleton.Instance.rutaUbicacionData.Te xt + "\\" + estrucTablas.tipoAtr[descar].nombAtr + "_" + estrucTablas.nombTab + ".txt", FileMode.Create, FileAccess.Write);
Escribir(archColumn, columnas[descar]);
}
}


class configuracion
{
String nombTabla;
String nombArchivoOrigen;
String tipoArchivo;
String hojaExcel;
int numRegistros;
List<tipoAtrib> tipoAtrib = new List<tipoAtrib>();

public string nombTab
{
get
{
return nombTabla;
}
set
{
nombTabla = value;
}
}

public string nombArchOrigen
{
get
{
return nombArchivoOrigen;
}
set
{
nombArchivoOrigen = value;
}
}

public string tipoArch
{
get
{
return tipoArchivo;
}
set
{
tipoArchivo = value;
}
}

public List<tipoAtrib> tipoAtr
{
get
{
return tipoAtrib;
}
set
{
tipoAtrib = value;
}
}

public string hojaExc
{
get
{
return hojaExcel;
}
set
{
hojaExcel = value;
}
}

public int numRegis
{
get
{
return numRegistros;
}
set
{
numRegistros = value;
}
}

En la linea public void EscrituraCarg(List<Hashtable> columnas, configuracion estrucTablas, int numTablas)

columnas es una lista de hashtables , configuracion es una estructura que contiene lo que te coloque debajo de ese metodo EscrituraCarg

int numTablas es un entero cualquiera.
  #11 (permalink)  
Antiguo 28/05/2008, 14:25
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

ok ya da un poco mas de panoramo ahora la linea donde invocas a EscrituraCarg(List<Hashtable> columnas, configuracion estrucTablas, int numTablas)
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #12 (permalink)  
Antiguo 28/05/2008, 14:31
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Esto es parte de una clase Factory que implemento

public void DoIt(List<Hashtable> colum, Escritura escribir, Lectura leer, configuracion estructura, int numTablas)
{
colum = leer.leerCargaTxt(estructura);
if (colum != null) escribir.EscrituraCarg(colum, estructura, numTablas);
}

y leerCargaTxt es el metodo que te puse al principio del hilo
  #13 (permalink)  
Antiguo 28/05/2008, 14:51
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

ok esta perfecto pero esto casi seguro q una de las invocaciones de esa list<hashtable> esta haciendo un loop sin fin en el get mas q en el set.

una vez mas la linea donde estas invocando a ese DoIt(obj.column,.....)
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #14 (permalink)  
Antiguo 28/05/2008, 14:58
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Esta es la clase Factory

class Factory
{
public Base GetObject(string tipoArch)
{
Base tipoProc = null;
switch (tipoArch)
{
case "Excel":
tipoProc = new archExcel();
break;
case "Fijo":
tipoProc = new archFijo();
break;
case "Delimitado":
tipoProc = new archDelimitado();
break;
}
return tipoProc;
}
}
interface Base
{
void DoIt(List<Hashtable> colum, Escritura escribir, Lectura leer, configuracion estructura, int numTablas);
}
class archExcel : Base
{
public void DoIt(List<Hashtable> colum, Escritura escribir, Lectura leer, configuracion estructura, int numTablas)
{
colum = leer.leerCargaExcel(estructura, estructura.hojaExc);
if (colum != null) escribir.EscrituraCarg(colum, estructura, numTablas);

}
}
class archFijo : Base
{
public void DoIt(List<Hashtable> colum, Escritura escribir, Lectura leer, configuracion estructura, int numTablas)
{
int[] anchos = leer.LeerConfigAnchos(estructura);
colum = leer.leerCargaAnchoFijo(estructura, anchos);
if (colum != null) escribir.EscrituraCarg(colum, estructura, numTablas);

}
}
class archDelimitado : Base
{
public void DoIt(List<Hashtable> colum, Escritura escribir, Lectura leer, configuracion estructura, int numTablas)
{
colum = leer.leerCargaTxt(estructura);
if (colum != null) escribir.EscrituraCarg(colum, estructura, numTablas);
}
}


Y este es el metodo ue comienza toda la ejecucion de la carga

public void EjecutarCarga()
{
try
{
Lectura leer = new Lectura();
List<configuracion> estructura = leer.leerConfig(Singleton.Instance.RutaArchConfigu racion.Text);//Lee la configuracion inicial de tablas y atributos
if (estructura == null) throw new ExceptionFinEjecucion();//Tira una excepcion si hubo problemas con el archivo de estructura
Escritura escribir = new Escritura();
for (int numTablas = 0; numTablas < estructura.Count; numTablas++)
{
List<Hashtable> colum = new List<Hashtable>();//Lista de Hashtables donde van las columnas de cada tabla
Factory factory = new Factory();//Decide a que tipo de archivo ir
Base obj = factory.GetObject(estructura[numTablas].tipoArch);
obj.DoIt(colum, escribir, leer, estructura[numTablas], numTablas);//Va a la ejecucion de ese tipo de archivo
}
escribir.EscrituraDiccio(estructura);
}
catch (ExceptionFinEjecucion ex)
{
log.Add(DateTime.Now + " : " + ex);
}
Singleton.Instance.resultados.Items.Add(DateTime.N ow + ": Fin de la ejecucion ");
Singleton.Instance.progreso.Value = 100;
}

Desde aqui llamas al DoIt de la clase factory segun sea elc aso del archivo que estes leyendo (Excel,delimitado,Ancho fijo)
  #15 (permalink)  
Antiguo 28/05/2008, 15:08
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

ok retomando lo anterior todavia podemos hacer unas cuantas optimizaciones al codigo para evitar tener problemas de exceso de memoria.

public void EscrituraCarg(List<Hashtable> columnas, configuracion estrucTablas, int numTablas)
{
for (int descar = 0; descar < columnas.Count; descar++)
{
FileStream archColumn = new FileStream(Singleton.Instance.rutaUbicacionData.Te xt + "\\" + estrucTablas.tipoAtr[descar].nombAtr + "_" + estrucTablas.nombTab + ".txt", FileMode.Create, FileAccess.Write);
Escribir(archColumn, columnas[descar]);
archColumn.Close(); // liberamos ese stream y no dentro del escribir
}

porque hacer esto, garantizar q al estar en el mismo ambito no se ocupe mas tiempo y memoria. digo sigo revisando q podria ser pero hagamos algunos cambios para poder optimizar tiempo y memoria
}
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #16 (permalink)  
Antiguo 28/05/2008, 15:30
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

No existe un manera de liberar memoria antes de pasar a la serializacion, ya prove con garbageCollector pero no me funcion quizas no lo utilize bien que opinas.
  #17 (permalink)  
Antiguo 28/05/2008, 15:49
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

el detalle es q mucho de los genericos no tienen implementado el IDisposable.
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #18 (permalink)  
Antiguo 28/05/2008, 15:57
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Inclusive Peter estoy chequeando y el archivo Binario se esta creando solo que de forma incompleta pq me imagino que se corta su creacion cuando da el out of memory exception y lo deja escrito de manera incompleta
  #19 (permalink)  
Antiguo 28/05/2008, 16:04
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

si es eso abria q checar si te conviene usar referencias

es decir

Escribir (ref list<hashtables>,....)

y asi reducir tambien un poco la memoria usada solo pasando la referencia de esa coleccion
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #20 (permalink)  
Antiguo 28/05/2008, 16:08
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Perdona Peter pero no entendi esta ultima sugerencia.
  #21 (permalink)  
Antiguo 28/05/2008, 16:12
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

si cuando haces

Escribir(list<hashtable> ...

en vez de crear un nuevo espacio para el list hashtable lo q haces es pasar la referencia al objeto de la invocacion

algo asi como usar & en c++
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #22 (permalink)  
Antiguo 28/05/2008, 16:29
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Probe colocando algunos valores por referencia y nada.
  #23 (permalink)  
Antiguo 28/05/2008, 17:22
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

cuanto se dispara tu proceso en uso de memoria?
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #24 (permalink)  
Antiguo 29/05/2008, 08:09
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

Peter disculpa que no te respondiera antes pero estuve haciendo un poco de investigacion , para poder darte un poco mas de luces en el problema, el error es este

http://www.codeproject.com/KB/cs/Lar...__Trouble.aspx

Aqui nos hablan de LOH (Large Object Heap) , lo que entiendo es que los objetos de estilo Hashtable (LOH) reservan en memoria un Heap de memoria y cuando lo llenan obtenemos el error de OutOfMemory Exception yo aplique este pedazo del codigo

Catch(OutOfMemory Exception)
{
}
Finally
{
array = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}

Con esto logre que no se cayera la aplicacion y me escribiera el archivo con la tabla de hash, ahora tenemos 2 problemas cuando lo trato de leer me da un error y dice que no puede terminar de deszerializar , no obstante ese no es el mas grave sino que inclusive con las modificacion el archivo no se esta guardando completo


Que opinas...
  #25 (permalink)  
Antiguo 29/05/2008, 08:57
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Error Hashtable

sabes q estuve pensando hacer

que fueces escribiendo cada hashtable y eliminandola despues de escribir asi garantizas q tienes espacio disponible despues de la primera escritura
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #26 (permalink)  
Antiguo 29/05/2008, 09:07
 
Fecha de Ingreso: julio-2006
Mensajes: 150
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Error Hashtable

El problema Peter es que en el caso que estoy ahorita estoy escribiendo 1 sola tabla de hash y a la primera cae en el out of memory como te dije ya lo controlo pero no me escribe la tabla completa dentro del hash.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:33.