尝试通过启用AspCompat使IIS 7.5上的经典ASP Web应用程序在STA模式下运行。由于实例化的COM对象不是线程安全的,因此这是一个很难的要求。
<%@ Page Language="VBScript" AspCompat="true" Debug="false" %>
虽然通过AspCompat强制设置,但渲染网站时的行为似乎不会成为结果。
预期的行为:
我知道这是糟糕的表现。但遗憾的是,这是运行传统ComServer的一项艰难要求。
当有多个并行请求来自同一客户端时,此行为可见。但是,当多个请求来自不同的客户端时,行为会发生变化:
操作3导致ComServer有时会失败,从而导致COMExceptions。
虽然问题可能是由于COMObject的设计不好引起的,但我无法改变这一点。我唯一能做的就是使用Application Lock围绕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中实例化,如示例中所示。但是,这不会改变从其他客户端访问页面时的行为。
答案 0 :(得分:0)
好的,我们已经有了这个,这就是我找到解决方案的方法..在我们的案例中,我认为它与父路径相关联,但也可能是会话状态......
浏览到C:\ Documents and Settings \ $您的用户名$ \ My Documents \ IIS 7.5 \ config
打开applicationHost.config
找到
部分将该部分更改为以下内容...默认情况下,它只有缓存和空限制位,但您可以随意调整任何不需要的参数。
<asp
enableParentPaths="true"
bufferingOn="true"
errorsToNTLog="true"
appAllowDebugging="true"
appAllowClientDebug="true"
scriptErrorSentToBrowser="true">
<session allowSessionState="true" />
<cache diskTemplateCacheDirectory="%TEMP%\iisexpress\ASP Compiled Templates" />
<limits />
</asp>
保存并重新启动iis 7.5。
答案 1 :(得分:0)
如果它是围绕使用应用程序锁的COMObject访问
但是,如果你以样本格式写这样的东西来获得一个想法。
Application["Counter"] = (int) Application["Counter"] + 1;
然后您将需要使用锁定和解锁,如下所示:
Application.Lock();
Application["Counter"] = (int) Application["Counter"] + 1;
Application.Unlock();
这是因为线程可能在Application对象的读取和写入之间被中断,因此另一个线程可能会改变为&#34; Counter&#34;存储的值。