我的excel正在编写时出现问题,我无法停止执行

时间:2018-11-26 17:55:08

标签: c# excel winforms

我在这里有一种情况,我有一个程序,出口是一个excel文件,可以,但是有时我要编写一个很大的Excel文件,在某些情况下,我需要停止该程序并终止该进程,再过一个小时再做一次。但是一旦开始编写过程,就只能在停止使用Visual Studio时停止,重要的是要知道我正在使用表单应用程序,我试图创建一个在不运行过程时可以工作的Button。

进程运行时好像无法访问我的表单。

有人可以帮助我解决这种情况吗?

1 个答案:

答案 0 :(得分:3)

创建Excel应用程序时,可以有效地创建一个新进程EXCEL.EXE。您可以在“进程”选项卡上的“任务管理器”(在“应用程序”部分中)中找到它。您只能通过终止Excel进程来停止操作-别无选择。

为了释放UI线程,应在另一个线程上运行Excel操作。 Task是完美的选择。由于Excel是非托管代码,因此您需要发布全部对其对象的引用。这意味着必须释放代码中使用的每个属性,每个对象。但是...这还不够。事实是EXCEL.EXE进程可能仍在进程列表中-您可以在背景进程部分中看到它。在某些情况下,该过程可能会消失。

总结一下我所说的内容,这是您需要的基本骨架:

1)创建适用于Excel的过程,将其包装在Task中并运行。

2)创建单独的过程,该过程可以由另一个按钮调用以停止     Excel过程。此过程还可以处理成功退出的情况。

using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;

namespace WinForms
{
    public partial class Form1 : Form
    {

        // Hold reference to Excel
        private Process xlProc = null;

        private void OnRun(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                // Create new instance of EXCEL.EXE
                var xlApp = new Excel.Application { Visible = true };

                // Get Excel proccess in order to kill it
                var handle = new IntPtr(xlApp.Hwnd);
                xlProc = Process.GetProcesses().Where(p => p.MainWindowHandle == handle).First();

                // Create new workbook
                var xlBook = xlApp.Workbooks.Add();
                var xlSheet = xlBook.Sheets[1] as Excel.Worksheet;

                // Do some operation
                xlSheet.Cells[1].Value = "Hello from .NET!";

                // Quit
                xlBook.Close(SaveChanges: false);
                xlApp.Quit();

                Marshal.ReleaseComObject(xlApp);
                Marshal.ReleaseComObject(xlBook);
                Marshal.ReleaseComObject(xlSheet);

                GC.Collect();
                GC.WaitForFullGCComplete();

                KillExcel();

            });
        }

        // Kill Excel process if it still exists
        private void KillExcel()
        {
            if (!xlProc.HasExited)
            {
                xlProc.Kill();
            }
        }
    }
}