加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 代码运行时退出Interop控制的Excel

发布时间:2020-12-15 21:45:29 所属栏目:百科 来源:网络整理
导读:我在C#中编写了一个Excel包装器,以便允许在批处理过程中运行Excel工作簿(在JobScheduler下).我的问题是…… 如果代码运行时间过长或需要通过作业调度程序终止,则包装器需要处理此终止事件.为此,我补充道 SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCt
我在C#中编写了一个Excel包装器,以便允许在批处理过程中运行Excel工作簿(在JobScheduler下).我的问题是……

如果代码运行时间过长或需要通过作业调度程序终止,则包装器需要处理此终止事件.为此,我补充道

SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck),true);

进入代码.在ConsoleCtrlCheck方法中,我调用一个公共出口例程(在正常或终止情况下使用).根据MS建议,此路由执行以下操作.

关闭和发布工作簿
关闭并发布Excel
垃圾收集

然后退出调用的Excel方法的返回码(入口点).
这很好用.

但是,如果VBA代码仍在运行,则Interop对象将不响应工作簿关闭或应用程序退出调用.这可能是因为一切都很慢或者因为发出了模态对话框.
为了解决这个问题,我在这个常见程序的开头添加了以下内容……

>创建新线程以运行KillExcel方法
> KillExcel方法在指定时间内休眠(因此正常的退出代码有机会工作)然后杀死进程
>如果正常代码有效,则在线程上调用Abort

private static void Cleanup()
{
    // Give this X seconds then terminate
    mKillThread = new Thread(KillExcel);
    mKillThread.IsBackground = false;
    mKillThread.Start();
    ...
    // close the workbooks and excel application
    // Marshal.FinalReleaseComObject etc

    GC.Collect();
    GC.WaitForPendingFinalizers();

    // Not sure if necessary but makes sure Process gone
    try
    {
        Process p = Process.GetProcessById(mExcelPid);
        p.WaitForExit();
    }
    catch(ArgumentException)
    {}

    mKillThread.Abort();
}

private static void KillExcel()
{
    Thread.Sleep(Settings.Default.KillWaitMilliSeconds);

    if (mLog.IsInfoEnabled)
        mLog.Info(string.Format("Waited {0} seconds,killing Excel process [{1}]",Settings.Default.KillWaitMilliSeconds/1000,mExcelPid));

    try
    {
        Process p = Process.GetProcessById(mExcelPid);

        if (!p.HasExited)
            p.Kill();
    }
    catch(ArgumentException)
    {
    }
}

我的问题是,有没有更好的方法来解决这个问题,或者这是为了确保在作业终止事件中删除excel进程的必要方式?

解决方法

你正在做的几乎是完全确保Excel退出的标准方法.鉴于有涉及COM Interop,并且excel有一个讨厌离开孤立实例的习惯,你遵循的方法几乎是万无一失的.

但是,如果您可以访问vba代码并且可以控制它,则可以执行一项基本操作来确保VBA代码允许其他代码运行.

DoEvents

根据我的经验,在运行大量计算之前和之后放置一行代码通常允许excel正确处理例程事件.虽然通常建议将其用于UI相关操作,但它也可以使工作表/应用程序事件正常工作.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读