2017-04-05 75 views
1

我正在使用本地.mdf文件,并执行一些查询到数据库,我使用USING块来确保SqlConnection和SqlReader被正确处置。vb.net使用SqlConnection不释放文件使用

然后我尝试读取文件的数据以生成文件的MD5散列,但它说文件仍在使用中。

代码不是最清洁的,这是我第一次使用VB.NET应用程序中的Sql工作。

SQL插入:

Dim finalW As String = "" 
Dim finalO() As String 
Dim currentcounter As Integer = 0 
For Each Dir As String In System.IO.Directory.GetDirectories(Pathfinder) 
    Dim dirInfo As New System.IO.DirectoryInfo(Dir) 
    Dim temp As New List(Of String) 
    For Each currentFile In Directory.GetFiles(Pathfinder & "\" & dirInfo.Name & "\", "*.png", SearchOption.TopDirectoryOnly) 
     temp.Add(Path.GetFileName(currentFile)) 
    Next 
    If temp.Count <> 0 Then 
     finalW = temp.Find(AddressOf GetNewIcon) 
     finalO = temp.FindAll(AddressOf GetOldIcon).ToArray 
     If finalW <> "" Then 
      Using con As New SqlClient.SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=""" & PathFinal & "ImaginiDB.mdf"";Integrated Security=True") 
       con.Open() 
       Using cmd = con.CreateCommand() 
        cmd.CommandType = CommandType.Text 
        cmd.CommandText = "INSERT NewIcon (Name) VALUES ('" & finalW.Trim() & "')" 
        cmd.Connection = con 
        cmd.ExecuteNonQuery() 
       End Using 
       currentcounter = currentcounter + 1 
       Dim Id As String = "" 
       Using command = con.CreateCommand() 
        command.CommandType = CommandType.Text 
        command.CommandText = "SELECT * FROM NewIcon WHERE Name='" & finalW & "'" 
        Using reader As SqlDataReader = command.ExecuteReader() 
         While reader.Read() 
          Id = reader(0) 
         End While 
        End Using 
       End Using 
       For Each item As String In finalO 
        Using cmd2 = con.CreateCommand() 
         cmd2.CommandType = CommandType.Text 
         cmd2.CommandText = "INSERT OldIcon (NID,Name) VALUES ('" & Id & "','" & item.ToString.Trim() & "')" 
         cmd2.Connection = con 
         cmd2.ExecuteNonQuery() 
        End Using 
        currentcounter = currentcounter + 1 
       Next 
       Dim cur As Long = currentcounter * 100/counter 
       SetProgress(cur) 
      End Using 
     End If 
    End If 
Next 
GC.Collect() 
GC.WaitForPendingFinalizers() 
SetLabel4Text("FINISHED IMPORT", Color.Red) 

MD5代追着这个过程完成:

Public Function GenMD5(ByVal Filename As String) As String 
    Dim MD5 = System.Security.Cryptography.MD5.Create 
    Dim Hash As Byte() 
    Dim sb As New System.Text.StringBuilder 
    Using st As New IO.FileStream(Filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) 
     Hash = MD5.ComputeHash(st) 
    End Using 
    For Each b In Hash 
     sb.Append(b.ToString("X2")) 
    Next 
    Return sb.ToString 
End Function 
+0

有时候,con.close()结束前使用可以帮助...不确定,如果这有助于你的情况。 – muffi

+0

@ muffi刚刚在每次使用结束时尝试过,但仍然得到错误。 – Mederic

+0

您应该阅读ADO.NET中的连接池。 'SqlConnection'是一个轻量级的对象,实际的数据库连接存在于较低的级别。连接池意味着多个'SqlConnection'对象将使用相同的底层连接对象,并且系统会在关闭SqlConnection后加速打开一段时间,以加速后续的使用。 – jmcilhinney

回答

1

,以便通过@jmcilhinney在评论中提到 不同的连接使用不同的池作为MSDN说:

当第一次打开连接时,连接池基于创建,该算法将池与连接中的连接字符串 相关联。

因此,我决定实施方法:

SqlConnection.ClearPool(connection As SqlConnection) 

我放在这只是我的最终使用前:

Dim cur As Long = currentcounter * 100/counter 
    SetProgress(cur) 
    SqlConnection.ClearPool(con) 
End Using