【发布时间】:2014-06-13 09:59:01
【问题描述】:
尝试通过启用 AspCompat 使 IIS 7.5 上的经典 ASP webapp 在 STA 模式下运行。这是一个硬性要求,因为实例化的 COM 对象不是线程安全的。
<%@ Page Language="VBScript" AspCompat="true" Debug="false" %>
虽然设置是通过 AspCompat 强制设置的,但呈现网站时的行为似乎没有结果。
预期行为:
- 在每次页面请求时,ComServer.exe 都会启动、执行一些工作并关闭。
- 当另一个请求到达时,处理等待第一个请求完成。
我知道这是糟糕的表现。然而遗憾的是,这是运行旧版 ComServer 的一项硬性要求。
当有来自同一个客户端的多个并行请求时,此行为是可见的。但是,当多个请求来自不同的客户端时,行为会发生变化:
- 每批请求后,ComServer 都会关闭。
- 如果只有一个请求,则 ComServer 在请求后停止
- 如果有多个请求,都在同一个 ComServer 下处理
操作 3 有时会导致 ComServer 失败,从而导致 COMExceptions。
虽然问题可能是由于 COMObject 的设计不当造成的,但我无法更改。我唯一能做的就是使用应用程序锁来围绕 COMObject 访问
Dim oComSvr as object
oComSvr=Server.CreateObject("com_svr.my_svr")
...
Application.Lock
returnValue=oComSvr.selectform(value1, value2, ...)
Application.Unlock
但是,这可以防止大多数 COMExceptions,但仍有特定的时间会导致 COMException。
如果对同一 IIS 服务器的多个请求来自不同的客户端,我可以做些什么来强制 STA 行为不变。
尝试按照这篇文章实现 Page_Load 以防止在 STA 模式之前创建对象。 http://technet.microsoft.com/en-ca/zwk9h2kb(v=vs.95).aspx
看起来 AspCompat 是否被忽略了。
[COMException (0x800706be): Creating an instance of the COM component with CLSID {B28A581A-6CE3-46E9-871F-B2E129F7D238} from the IClassFactory failed due to the following error: 800706be.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86
System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230
System.Activator.CreateInstance(Type type, Boolean nonPublic) +67
System.Activator.CreateInstance(Type type) +6
System.Web.HttpServerUtility.CreateObject(String progID) +122
ASP.myapp.Page_Load() +1670
System.Web.Util.CalliHelper.ArglessFunctionCaller(IntPtr fp, Object o) +8
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +8760147
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
更新: 在这里和这里阅读,重要的是在哪里实例化 STA 对象。在构造期间实例化对象将导致此问题。 http://technet.microsoft.com/en-ca/zwk9h2kb(v=vs.95).aspx http://msdn.microsoft.com/en-us/library/5dws599a(vs.71).aspx
尝试在 Page_Load 中实例化,如示例中所示。但是,这不会改变从其他客户端访问页面时的行为。
【问题讨论】:
标签: iis asp-classic com iis-7.5 visual-foxpro