1

我正在编写一个通过互操作打开 Microsoft Excel 的应用程序。

我遇到的问题是,如果应用程序本身锁定或内存泄漏,我的应用程序将被阻塞并且不会继续线程。

我有一个父线程,它查看一个目录并为每个文件循环写入

转换("src.xls","src.pdf",null); 有时说,例如,如果我们给 excel 一个无法打开的文件类型,它将被锁定。这将锁定我的线程,迫使我不得不终止该进程。

public static class ExcelConverter
{
    public static bool Convert(string srcFile, string destinationFile, object[] parameters)
    {
        bool bStatus = false;
        Workbook excelWorkBook = null;
        Excel.Application application = null;

        try
        {


        application = new Excel.Application();
        object missingParam = Type.Missing;


            excelWorkBook = application.Workbooks.Open(srcFile);

            if (excelWorkBook != null)
            {
                excelWorkBook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, destinationFile);
            }
            bStatus = true;
        }
        catch (Exception)
        {

            bStatus = false;
        }
        finally
        {
            if (excelWorkBook != null)
            {
                excelWorkBook.Close(false);
                excelWorkBook = null;
            }

            if (application != null)
            {
                application.Quit();
                application = null;
            }

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

        return bStatus;
    }
}
4

2 回答 2

3

例如,如果我们给 excel 一个无法打开的文件类型,它将被锁定

它可能试图显示一个告诉用户它的对话框。通过设置 application.Visible = true 来调试它,这样您就可以实际看到对话框。通过在 Open() 调用中指定更多参数来修复它。Password、Notify 和 CorruptLoad 参数有作用。更好地筛选文件是一个明显的解决方法,Excel 真正设计为交互式和健谈的问题。

您不必担心线程,Excel 是单线程 COM 对象,COM 确保以线程安全的方式调用接口方法。在您的情况下,这是通过实际创建一个线程来为互操作对象提供一个安全的家。

于 2012-06-01T12:18:08.947 回答
2

在这里,您可能想要创建一个扩展MarshalByRefObject对象的对象,您可以在新对象中生成该对象AppDomain以进行转换。完成后,只需卸载AppDomain并清除所有内存。

于 2012-06-01T14:49:30.127 回答