winforms C# WinForm - EXE在关闭主窗体时不终止

zsohkypk  于 2022-11-17  发布在  C#
关注(0)|答案(1)|浏览(300)

我正在开发一个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块中,我确实意识到那里有一些冗余,但我已经绝望了。
一旦文件被证明对列标题的预定义列表有效,第二个方法被调用。一旦执行此操作,关闭主窗体SEEMS以关闭应用程序,但在任务管理器中仍有一个延迟进程,其中有一个线程。
我曾尝试将Application.Exit()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检测到误报的原因。我不知道此延迟线程是什么,也不知道如何获得正确终止它的代码。

ct3nt3jp

ct3nt3jp1#

我通过实现一个完全基于NPOI的阅读解决方案而不使用OleDB来解决这个问题(很好的解决方案):

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现在正确终止!

相关问题