为 ASP.NET WebForms Web 应用程序中的所有用户保持一个互操作办公应用程序处于活动状态(直到 IIS 重新启动)
Keeping one interop office application alive (until IIS restart) for all users in ASP.NET WebForms Web Application
我有一个 ASP.NET 4.5 WebForms 网络应用程序,使用 Microsoft.Office.Interop.Word
将 RDF/DOC/TXT 转换为 PDF 文件。我想在应用程序的整个生命周期(直到 IIS 重新启动)中保持 Microsoft.Office.Interop.Word.Application
的一个实例打开。原因是初始化 Application
是资源密集型的。尝试使用程序集转换文档需要很长的周转时间(4-5 秒以上),即使对于小文档也是如此,其中大部分时间在 Application.Start()
和 Application.Quit()
中。我希望通过保留应用程序本身,我将能够为我的用户增加文档转换吞吐量。
这样做正确吗?实现此目的的最佳方法是将 Application
存储为非静态 class 的 static
属性 吗?我这样做的方式正确吗?
//@see: https://www.codeproject.com/Tips/592957/Converting-Document-Word-Excel
using Microsoft.Office.Interop.Word;
public class DocManager
{
//Microsoft.Office.Interop.Word.Application
private static Application msWordDoc = null;
// C# doesn't have optional arguments so we'll need a dummy value
private static object oMissing = System.Reflection.Missing.Value;
//Microsoft.Office.Interop.Word.Document
private Document doc = null;
public DocManager()
{
if (msWordDoc == null)
{
//1 instance to be available to all users across multiple requests
msWordDoc = new Application
{
Visible = false,
ScreenUpdating = false
};
}
}
}
当 .NET 应用程序 stopped/restarted 我想确保 Word 互操作应用程序正确关闭和发布 - 即使我的应用程序崩溃。我需要在哪里插入代码? CodeProject 中有这样一个例子:
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(msWordDoc);
msWordDoc = null;
}
catch (Exception exReleaseObject)
{
msWordDoc = null;
// Console.WriteLine(CMSResourceFile.REALESE_FAILED+ exReleaseObject);
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
如果您想确保 Word 进程正确完成,您需要立即释放所有基础 COM 对象。使用 System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article. You may also find the When to release COM objects in Office add-ins developed in .NET 篇文章很有帮助。
请注意,Microsoft 目前不建议也不支持从任何无人值守的非交互式客户端应用程序或组件(包括 ASP、ASP.NET、DCOM和 NT 服务),因为当 Office 在此环境中 运行 时,Office 可能表现出不稳定的行为 and/or 死锁。
如果您正在构建 运行 在服务器端上下文中的解决方案,您应该尝试使用已针对无人值守执行安全设置的组件。或者,您应该尝试找到至少允许 运行 客户端部分代码的替代方案。如果您从服务器端解决方案使用 Office 应用程序,该应用程序将缺少许多 运行 成功所必需的功能。此外,您将承担整体解决方案稳定性的风险。在 Considerations for server-side Automation of Office 文章中阅读更多相关信息。
作为解决方法,如果您只处理打开的 XML 文档,您可以考虑使用 Open XML SDK。或者考虑使用为服务器端执行而设计的任何第三方组件。
我有一个 ASP.NET 4.5 WebForms 网络应用程序,使用 Microsoft.Office.Interop.Word
将 RDF/DOC/TXT 转换为 PDF 文件。我想在应用程序的整个生命周期(直到 IIS 重新启动)中保持 Microsoft.Office.Interop.Word.Application
的一个实例打开。原因是初始化 Application
是资源密集型的。尝试使用程序集转换文档需要很长的周转时间(4-5 秒以上),即使对于小文档也是如此,其中大部分时间在 Application.Start()
和 Application.Quit()
中。我希望通过保留应用程序本身,我将能够为我的用户增加文档转换吞吐量。
这样做正确吗?实现此目的的最佳方法是将 Application
存储为非静态 class 的 static
属性 吗?我这样做的方式正确吗?
//@see: https://www.codeproject.com/Tips/592957/Converting-Document-Word-Excel
using Microsoft.Office.Interop.Word;
public class DocManager
{
//Microsoft.Office.Interop.Word.Application
private static Application msWordDoc = null;
// C# doesn't have optional arguments so we'll need a dummy value
private static object oMissing = System.Reflection.Missing.Value;
//Microsoft.Office.Interop.Word.Document
private Document doc = null;
public DocManager()
{
if (msWordDoc == null)
{
//1 instance to be available to all users across multiple requests
msWordDoc = new Application
{
Visible = false,
ScreenUpdating = false
};
}
}
}
当 .NET 应用程序 stopped/restarted 我想确保 Word 互操作应用程序正确关闭和发布 - 即使我的应用程序崩溃。我需要在哪里插入代码? CodeProject 中有这样一个例子:
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(msWordDoc);
msWordDoc = null;
}
catch (Exception exReleaseObject)
{
msWordDoc = null;
// Console.WriteLine(CMSResourceFile.REALESE_FAILED+ exReleaseObject);
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
如果您想确保 Word 进程正确完成,您需要立即释放所有基础 COM 对象。使用 System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article. You may also find the When to release COM objects in Office add-ins developed in .NET 篇文章很有帮助。
请注意,Microsoft 目前不建议也不支持从任何无人值守的非交互式客户端应用程序或组件(包括 ASP、ASP.NET、DCOM和 NT 服务),因为当 Office 在此环境中 运行 时,Office 可能表现出不稳定的行为 and/or 死锁。
如果您正在构建 运行 在服务器端上下文中的解决方案,您应该尝试使用已针对无人值守执行安全设置的组件。或者,您应该尝试找到至少允许 运行 客户端部分代码的替代方案。如果您从服务器端解决方案使用 Office 应用程序,该应用程序将缺少许多 运行 成功所必需的功能。此外,您将承担整体解决方案稳定性的风险。在 Considerations for server-side Automation of Office 文章中阅读更多相关信息。
作为解决方法,如果您只处理打开的 XML 文档,您可以考虑使用 Open XML SDK。或者考虑使用为服务器端执行而设计的任何第三方组件。