Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-03-2012
Gattaca Gattaca is offline
Miembro
 
Registrado: feb 2009
Posts: 31
Poder: 0
Gattaca Va por buen camino
Angry Increíble error el Delphi va muy rapido!

Hola!

Tengo un increíble problema!!

Veran estoy leyendo un archivo binario a una velocidad creo que muy rapida, causandome el error "EAccessViolation", y la unica forma de solventarlo es agregando un "sleep(1)", haciendo que mi applicación valla más lenta!.

Esté es el loop principal llamado desde un menu para cargar el archivo.
La aplicación no dejo de darme errores, hasta que agregue el sleep antes de llamar a ReadItem()
Código Delphi [-]
      // Objects, walls, grounds, etc...
      for itemId := 100 to ItemCount - 100 do
      begin
        // con esta linea no me da error y carga más de 30000+ objetos del archivo binario
        // sin ella, me dá error!
        sleep(1);
        application.ProcessMessages;
        SetItem(itemId-100, ReadItem(itemId));
        //writeln(flogfile, 'Successfully readed Item #' + inttostr(itemId) + '.');

      end;

MI funcion ReadItem
Código Delphi [-]
function TDatFile.ReadItem(Id: UInt16): TItem;
var value: byte;
    return: TItem;
    spriteId: UInt16;
begin
  try
    while (value <> $FF) do
    begin

      value := ReadData.ReadByte();

      case value of
        $00:
          ReadData.ReadUInt16();
        $17, $20, $FF, $01, $02, $03, $04, $05, $06, $07, $08,
        $0B, $0C, $0D, $0E, $0F, $10, $11, $12,
        $13, $14, $15, $18, $1B, $1F, $1C
        : begin end;
        $09, $0A: begin ReadData.ReadUInt16(); end;
        $1A, $1D: begin ReadData.ReadUInt16(); end;
        $16, $19: begin ReadData.ReadUInt16(); ReadData.ReadUInt16(); end;
        $1E: begin ReadData.ReadUInt16(); end;
        else begin
          writeln(Flogfile, '   ERROR: Invalid Integer: ' + inttostr(value) + ' at item #' + inttostr(Id));
        end;
      end;

    end; // End flags

    return := TItem.Create;

    return.ID := Id;

    return.Width := ReadData.ReadByte();
    return.Height := ReadData.ReadByte();

    if (return.Width > 1) or (return.Height > 1) then
      return.CropImage := ReadData.ReadByte();

    return.Blendframes := ReadData.ReadByte();
    return.xRepeat := ReadData.ReadByte();
    return.yRepeat := ReadData.ReadByte();
    return.zRepeat := ReadData.ReadByte();
    return.Animations := ReadData.ReadByte();

    setLength(return.Sprites, return.SpritesCount);

    try
      for spriteId := 0 to return.SpritesCount - 1 do
      begin
        return.Sprites[spriteId] := ReadData.ReadUInt16();

        //writeln(flogfile, ' Readed Sprite #' + inttostr(return.Sprites[spriteid]));
      end;
    except
       on E : Exception do
      writeln(flogfile, ' CRITICAL ERROR AT OBJECT #' + inttostr(id) + ': '#13 + E.ClassName+' error raised, with message : '+E.Message);
    end;

  finally
    result := return;
  end;
  {except
    on E : Exception do
      writeln(flogfile, ' CRITICAL ERROR: '#13 + E.ClassName+' error raised, with message : '+E.Message);
  end; }
end;

Porfavor ayudenme, no tengo idea de que está mal en mi codigo para que me tire ese error!!

Usando Embarcadero Delphi XE2
Windows 7 x64 Home Premium
Tengo derechos de admin.
Responder Con Cita
  #2  
Antiguo 03-03-2012
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Generalmente en la documentación de los dispositivos viene la información incluso ejemplos de como leer y escribir en ellos si es que lo permiten.

Sospecho que el dispositivo tenga un tiempo de espera entre una y otra llamada y por eso la función Sleep te ha resuelto el problema. Si tienes el manual o puedes contactar con alguien de la empresa fabricante te resolverá la duda, lo digo porque en una ocasión tuve que llamar nada menos que a Austria y me enviaron una Dll y ejemplos de uso........

Un Saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #3  
Antiguo 03-03-2012
Avatar de Héctor Randolph
[Héctor Randolph] Héctor Randolph is offline
Miembro Premium
 
Registrado: dic 2004
Posts: 882
Poder: 20
Héctor Randolph Va por buen camino
Probablemente el error se presenta al llamar la función ProcessMessages en intervalos tan reducidos de tiempo.
Te propongo espaciar las llamadas para que en lugar de hacerlo en cada ciclo se hagan cada 400 ciclos por poner un ejemplo, el número lo decides tu mismo.

Quedaría algo como esto:

Código Delphi [-]
   for itemId := 100 to ItemCount - 100 do
      begin
        // con esta linea no me da error y carga más de 30000+ objetos del archivo binario
        // sin ella, me dá error!
        //sleep(1);
         if itemId mod 400 = 0 then // Solamente se procesan los mensajes cada 400 ciclos
            application.ProcessMessages;
        SetItem(itemId-100, ReadItem(itemId));
        //writeln(flogfile, 'Successfully readed Item #' + inttostr(itemId) + '.');

      end;

Saludos
Responder Con Cita
  #4  
Antiguo 03-03-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Hola,
El problema tal vez esté en la creación del objeto de la clase TItem que regresa la función.

A mi una vez haciendo un trabajo para la facultad me salía un AV y todo parecía correcto; las creaciones y liberaciones. Yo estaba trabajando en una lista, a la vieja escuela con punteros, y no veía algo malo. Si dejaba corriendo mi aplicación llegaba el momento en que saltaba el AV. Luego debugueando, y controlando a mano, para ver donde saltaba descubrí que en realidad el error estaba en que el recorrido sobre la lista y las instrucciones que hacía se ejecutaban tan rápido que no daba tiempo a que las reservas de memoria me creara los nodos.

Lo tuve que solucionar forzandole a que se tome un tiempo entre un New() y el uso de la variable.
Muy posiblemente lo tuyo será un caso similar.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 04-03-2012
Gattaca Gattaca is offline
Miembro
 
Registrado: feb 2009
Posts: 31
Poder: 0
Gattaca Va por buen camino
Cita:
Empezado por Delphius Ver Mensaje
Hola,
El problema tal vez esté en la creación del objeto de la clase TItem que regresa la función.

A mi una vez haciendo un trabajo para la facultad me salía un AV y todo parecía correcto; las creaciones y liberaciones. Yo estaba trabajando en una lista, a la vieja escuela con punteros, y no veía algo malo. Si dejaba corriendo mi aplicación llegaba el momento en que saltaba el AV. Luego debugueando, y controlando a mano, para ver donde saltaba descubrí que en realidad el error estaba en que el recorrido sobre la lista y las instrucciones que hacía se ejecutaban tan rápido que no daba tiempo a que las reservas de memoria me creara los nodos.

Lo tuve que solucionar forzandole a que se tome un tiempo entre un New() y el uso de la variable.
Muy posiblemente lo tuyo será un caso similar.

Saludos,
Hola,

Ciertamente debo decir que tu problema tiene mucha coherencía, y es igual al mio, usando la función New he podido arreglar el error, cargando todos los objetos binarios (+30000) en menos de 1 segundo!

Estoy sorprendido como, aunque el codigo esté correcto, el puede no funcionar correctamente, y aún no me explico ¿cómo?, pero supongo que tiene que ver con la memoria, ya que leer un archivo binario en un loop for puede funcionar radicalmente rapido, causando así que donde está alojada mi variable en la memoria, sea reescribida a cada ó borrada a cada momento, según DelphiBasics.co.uk, la palabra reservada New tiene está pequeña explicación;

Código:
New is used when the storage is requirement is fixed in size. Use GetMem to dictate the exact storage size allocated.
El ejemplo dado usaba pointers, y solo tube que reescribir mi clase TItem a un record y crear un punto en la memoria que siempre sea fijo, acá usando New supongo.

En fin, ahora mi codigo funciona correctamente, y ya veo el buen uso de New con respecto a las memorias

Pido perdon si mi explicación suena incoherente, pero soy muy joven y estoy muy metido en esto de la programación.

Muchas gracias nuevamente a todos, ayudandome desde el 2009 jejeje
Un saludo!

Última edición por Gattaca fecha: 04-03-2012 a las 10:05:18.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Ayudenme Rapido, Rapido omarys Varios 6 04-06-2011 10:45:34
Talento increible..... egostar Humor 4 01-08-2008 08:04:37
Increible truco de magia!! FunBit Humor 5 25-10-2006 21:37:56
Rapido con Delphi, y Lento desde fuera de delphi JoseQ Varios 0 08-09-2005 11:54:48
La increíble tecla F1 en Delphi dec Varios 1 31-08-2005 23:26:45


La franja horaria es GMT +2. Ahora son las 14:29:26.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi