ArcObjects .NET - Cómo cerrar / liberar FeatureClass, Workspace, Factory

8

Tengo un proceso de larga duración. Quiero evitar fugas de recursos o conexiones de bases de datos no autorizadas.

A intervalos durante el proceso, quiero hacer esto:

  1. obtener una fábrica de espacio de trabajo de ArcSDE (Oracle)
  2. abrir un espacio de trabajo de fábrica (en ese momento obtengo una conexión de base de datos abierta)
  3. obtener una clase de entidad o tabla existente en el espacio de trabajo,
  4. consultar la clase de entidad o tabla, recorrer el cursor haciendo mi negocio
  5. luego suelte / cierre todo de manera que :

    • La conexión de la base de datos y el bloqueo de la tabla desde la perspectiva de ArcSDE / Oracle (como lo revela algo como "sdemon -o info -I users" o una consulta de la tabla sde.table_locks) se cierra / libera.
    • el proceso es resistente a los reinicios de ArcSDE / Oracle (es decir, no voy a dejar algo colgado que no funcionará más tarde después del reinicio nocturno)
    • Se liberan todas las referencias RCW, COM y memoria.

Básicamente, debido a la naturaleza de larga duración del proceso, quiero estar realmente seguro de que no tengo pérdidas de recursos o conexiones deshonestas, y mi proceso puede sobrevivir a los reinicios de ArcSDE / Oracle .

He visto discusiones como:

Y esto , de lo que cito

Cada fábrica de espacios de trabajo mantiene un grupo de espacios de trabajo activos conectados actualmente a los que hace referencia la aplicación. Cuando se llama a cualquiera de los métodos Open * enumerados anteriormente, la fábrica del espacio de trabajo verifica si un espacio de trabajo se ha abierto previamente con un conjunto de propiedades coincidentes. Si es así, se devuelve una referencia a la instancia existente.

Todo lo cual me sugiere que debería liberar (por ejemplo, la clase ComReleaser o el bucle Marshal.ReleaseComObject () equivalente), probablemente en este orden:

  • cursor
  • clase / mesa
  • espacio de trabajo
  • fábrica del espacio de trabajo

Luego hay discusiones como esta donde las personas hacen todo eso, y tal vez incluso espolvorean en System.GC.Collect () y su conexión a la base de datos sigue viva.

Oh gurús, ¿cuál es la droga final sobre esto?

MC5
fuente
1
¿Has probado algo tú mismo o solo estás pidiendo consejo? La apuesta más segura parece generar un nuevo hilo o proceso para hacer su trabajo periódico. De lo contrario, en mi opinión, funcionaría si logras rastrear todos los objetos y liberarlos de acuerdo con tu plan. Si tiene un control de mapa, también puede contener referencias a través de las capas.
Stefan
Estoy en progreso y estoy pidiendo consejo. Aquí hay una pregunta de seguimiento a su comentario: si realizo la tarea periódica en un subproceso de trabajo, ¿debería el trabajador liberar la fábrica del espacio de trabajo, o si es un singleton, causará problemas para otros subprocesos simultáneos posibles? Supongo que debería dejar la fábrica sola.
MC5
Hay muchos escritos sobre el modelo de subprocesamiento de objetos de arco. Lea edndoc.esri.com/arcobjects/9.2/net/… (9.2 pero todavía es válido, creo). Dice que los singeltons son singeltons por hilo, no por proceso. También tenga en cuenta que los hilos deben ser STA y que no puede pasar referencias de objetos de arco entre hilos. Entonces, si termina el subproceso de trabajo, debería limpiar las fábricas. También busque en su propio enlace a ESRI-forum donde ESRI recomienda el enhebrado como una solución para liberar conexiones.
Stefan

Respuestas:

4

Ya has cubierto muchos aspectos en tu publicación. Sin embargo, para ampliar su pregunta, siga siempre este patrón:

if (obj!=null)
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(obj);

obj = null;

Luego llame System.GC.Collect()para forzar al recolector de basura a eliminar cualquier referencia al DBMS.

El orden de lanzamiento debe ser Cursores, Características (IFeature), FeatureClasses, Workspaces y otros ArcObjects instanciados.

ArcGIS Desktop y la aplicación ArcEngine son STA (aplicación de subproceso único). No es seguro ni aconsejable utilizar ArcObjects en subprocesos (Trabajadores); Uno puede usar la serialización y deserialización de objetos para lograr esto. Para más detalles, eche un vistazo aquí .

Farid Cheraghi
fuente