Hola a todos, buenas tardes,
Tengo un problema espero puedan ayudarme, lo que pasa es que al usar "OleDbDataAdapter" con un
Dim strConn As String = "Provider=Microsoft.ACE.OLEDB.12.0;" &
"Data Source= C:Archivo.xls;" &
"Extended Properties=""Excel 12.0 Xml;HDR=No"""
y al final después de leer el archivo lo libero con OleDbDataAdapter.Dispose() , pero después al querer renombrar, borrar o mover me arroja un error, el cual es el siguiente "error por un componente externo" o "el archivo está siendo usado por otro proceso" pero si me espero un minuto para eliminarlo si me deja, incluso aunque encierre todo en un "using":
Using { resourcelist | resourceexpression }
[ statements ]
End Using
y al final intente eliminarlo aún debo esperar un minuto, al checar los procesos de Windows veo que el archivo no está siendo usado por ningún proceso, es como si se tardara en eliminar de la memoria.
Alguien de ustedes les ha pasado esto y si me pueden ayudar a solucionarlo muchas gracias.
Hola,
El problema es que OleDbDataAdapter.Dispose() libera el adaptador, pero no cierra la conexión subyacente (OleDbConnection), que es quien realmente tiene el fichero Excel abierto a nivel de sistema operativo. Por eso el adaptador ya no existe, pero el archivo sigue «bloqueado» cuando intentas renombrarlo o moverlo después.
La forma correcta es usar bloques Using tanto para la conexión como para el adaptador, que garantizan que todo se cierra y libera aunque salte una excepción por el camino:
Dim strConn As String = "Provider=Microsoft.ACE.OLEDB.12.0;" &
"Data Source=C:Archivo.xls;" &
"Extended Properties=""Excel 12.0 Xml;HDR=No"""
Using conexion As New OleDbConnection(strConn)
conexion.Open()
Using adaptador As New OleDbDataAdapter("SELECT * FROM [Hoja1$]", conexion)
Dim tabla As New DataTable()
adaptador.Fill(tabla)
' aqui procesas la tabla
End Using ' cierra y libera el adaptador
End Using ' cierra y libera la CONEXION, que es la que de verdad tenia el fichero abierto
Con Using, aunque no llames a Dispose() a mano en ningún momento, VB.NET se encarga de cerrarlo todo automáticamente al salir del bloque, incluso si el código de dentro lanza una excepción. Es el patrón recomendado precisamente para evitar este tipo de fugas de recursos (ficheros, conexiones, streams...) que quedan «colgados» aunque a simple vista parezca que ya los has liberado.
Si por lo que sea no puedes usar Using (código más antiguo con try/finally), asegúrate de llamar explícitamente a conexion.Close(), no solo a adaptador.Dispose(): son objetos distintos y liberar uno no libera el otro.
Carlos