我正在開發一個 WinForms 應用程式,它廣泛使用 OleDB(連同 NPOI)來讀取和撰寫 Excel 作業簿。我會先說,如果我只是啟動應用程式并立即關閉它,應用程式和 EXE 將正常終止。用戶可以執行的第一個操作是單擊按鈕以打開 XLSX 檔案。然后我在記憶體中初始化一個資料表并使用以下代碼填充它:
打開連接:
public static OleDbConnection GetConnection(string filePath)
{
var url = @"Provider=Microsoft.ACE.OLEDB.12.0;"
"Data Source=" filePath ";"
"Extended Properties='Excel 12.0 Xml; HDR=YES; IMEX=1;';";
try
{
var con = new OleDbConnection(url);
con.Open();
return con;
}
catch (Exception e)
{
throw new ArgumentException($"Unable to open connection to workbook with url \"{url}\"", e);
}
}
填寫資料表:
public static void PopulateDataTable(string filePath, DataTable dt)
{
using var con = GetConnection(filePath);
using var sda = new OleDbDataAdapter(new OleDbCommand("Select * From [" GetSheetName(con) "]", con));
sda.Fill(dt);
sda.Dispose();
con.Close();
con.Dispose();
}
第一種方法僅用于驗證檔案的標題,并由呼叫代碼顯式關閉和處理。它也在 using 塊中,我確實意識到那里有一些冗余,但我很絕望。
一旦根據預先確定的列標題串列證明檔案有效,就會呼叫第二種方法。執行此操作后,關閉主表單似乎會關閉應用程式,但任務管理器中仍有一個揮之不去的行程,其中有一個執行緒。
我已經嘗試將Application.Exit()and添加Environment.Exit(0)到 FormClosing 方法中,該方法確實殺死了行程,但在顯示沙漏并在事件查看器中記錄以下錯誤之前沒有:
Faulting application name: SomeApp.exe, version: 1.0.0.0, time stamp: 0x62cf0b31
Faulting module name: mso20win32client.dll, version: 0.0.0.0, time stamp: 0x62df2f51
Exception code: 0xc000041d
Fault offset: 0x000185ed
Faulting process id: 0x27f24
Faulting application start time: 0x01d8bc7d9dd155ac
Faulting application path: C:\Dev\VisualStudioProjects\SomeApp\Final\SomeApp.exe
Faulting module path: C:\Program Files (x86)\Common Files\Microsoft Shared\Office16\mso20win32client.dll
Report Id: 4a58bd92-6541-4def-a04d-01ed0668d38b
Faulting package full name:
Faulting package-relative application ID:
除了例外代碼 0xc0000005 之外,還記錄了第二個相同的事件。我懷疑這個問題也是導致 Windows Defender 誤報檢測的原因。我無法弄清楚這個揮之不去的執行緒是什么以及如何讓代碼正確地殺死它。
uj5u.com熱心網友回復:
我通過在不使用 OleDB 的情況下實作純基于 NPOI 的閱讀解決方案來解決此問題(擺脫困境):
public static void PopulateDatatableNPOI(string filePath, DataTable dt, bool createHeaders)
{
using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var sheet = new XSSFWorkbook(stream).GetSheetAt(0);
if (createHeaders)
{
var headerRow = sheet.GetRow(0);
foreach (var headerCell in headerRow)
dt.Columns.Add(headerCell.ToString());
}
for (int i = 1; i < sheet.PhysicalNumberOfRows; i )
{
var sheetRow = sheet.GetRow(i);
var dtRow = dt.NewRow();
dtRow.ItemArray = dt.Columns
.Cast<DataColumn>()
.Select(c => sheetRow.GetCell(c.Ordinal, MissingCellPolicy.CREATE_NULL_AS_BLANK).ToString())
.ToArray();
dt.Rows.Add(dtRow);
}
}
EXE 現在正確終止了!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/506815.html
