有时候在程序中需要删除某个文件,却出现"文件由另一个进程使用,不能删除"的错误,这往往是因为文件句柄资源没有关闭. 在C#中关闭句柄后有时仍出现,更加莫名其妙. 主要原因在于垃圾收集. 还是看代码清楚些.
using
System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
namespace Zrj.Test
... {
class TestDbCreate
...{
static void Main()
...{
Test1();
}
static void Test1()
...{
string file = "testdb.mdb";
File.Delete(file);
CreateDatabase(file);
Console.WriteLine("Database created.");
OleDbConnection cnn = new OleDbConnection();
cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + file;
cnn.Open();
// do something
cnn.Close();
Console.WriteLine("OleDbConnection Closed.");
int maxTick = 20 * 1000;
int spendTick = DeleteFile(file, maxTick);
if(spendTick < maxTick)
Console.WriteLine("Spend {1} ticks to delete {0}", file, spendTick);
else
Console.WriteLine("Spend {1} ticks to delete {0}, but not delete", file, spendTick);
}
static int DeleteFile(string file, int maxTick)
...{
int startTick = Environment.TickCount;
int tryCount = 0;
GC.Collect(); // 关键代码
do
...{
try
...{
File.Delete(file);
}
catch(IOException)
...{
++tryCount;
continue;
}
break;
}while(Environment.TickCount < (startTick+maxTick));
Console.WriteLine("Total try count is {0}.", ++tryCount);
return Environment.TickCount - startTick;
}
/**////<summary>使用ADOX.Catalog.Create生成Access数据库</summary>
static void CreateDatabase(string dbFileName)
...{
try
...{
string connectionString1 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbFileName;
object objCatalog = Activator.CreateInstance(Type.GetTypeFromProgID("ADOX.Catalog"));
object[] oParams = new object[] ...{ connectionString1 };
objCatalog.GetType().InvokeMember("Create", System.Reflection.BindingFlags.InvokeMethod, null, objCatalog, oParams);
System.Runtime.InteropServices.Marshal.ReleaseComObject(objCatalog);
objCatalog = null;
}
catch (Exception ex)
...{
Console.WriteLine("{0} 生成Access数据库出现错误! ", ex.ToString());
}
}
}
}
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
namespace Zrj.Test
... {
class TestDbCreate
...{
static void Main()
...{
Test1();
}
static void Test1()
...{
string file = "testdb.mdb";
File.Delete(file);
CreateDatabase(file);
Console.WriteLine("Database created.");
OleDbConnection cnn = new OleDbConnection();
cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + file;
cnn.Open();
// do something
cnn.Close();
Console.WriteLine("OleDbConnection Closed.");
int maxTick = 20 * 1000;
int spendTick = DeleteFile(file, maxTick);
if(spendTick < maxTick)
Console.WriteLine("Spend {1} ticks to delete {0}", file, spendTick);
else
Console.WriteLine("Spend {1} ticks to delete {0}, but not delete", file, spendTick);
}
static int DeleteFile(string file, int maxTick)
...{
int startTick = Environment.TickCount;
int tryCount = 0;
GC.Collect(); // 关键代码
do
...{
try
...{
File.Delete(file);
}
catch(IOException)
...{
++tryCount;
continue;
}
break;
}while(Environment.TickCount < (startTick+maxTick));
Console.WriteLine("Total try count is {0}.", ++tryCount);
return Environment.TickCount - startTick;
}
/**////<summary>使用ADOX.Catalog.Create生成Access数据库</summary>
static void CreateDatabase(string dbFileName)
...{
try
...{
string connectionString1 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbFileName;
object objCatalog = Activator.CreateInstance(Type.GetTypeFromProgID("ADOX.Catalog"));
object[] oParams = new object[] ...{ connectionString1 };
objCatalog.GetType().InvokeMember("Create", System.Reflection.BindingFlags.InvokeMethod, null, objCatalog, oParams);
System.Runtime.InteropServices.Marshal.ReleaseComObject(objCatalog);
objCatalog = null;
}
catch (Exception ex)
...{
Console.WriteLine("{0} 生成Access数据库出现错误! ", ex.ToString());
}
}
}
}
最后输出:
D:/Temp/test>testdc
Database created.
OleDbConnection Closed.
Total try count is 2.
Spend 31 ticks to delete testdb.mdb