Trying to for a Classic ASP webapp on IIS 7.5 to run in STA mode by enabling AspCompat. This is a hard requirement due to a COM Object being instantiated that is not thread safe.
<%@ Page Language="VBScript" AspCompat="true" Debug="false" %>
Although the settings is forced through AspCompat, the behaviour when rendering websites seems not to be consequent.
The expected behaviour:
I know this is bad performance whise. However sadly, this is a hard requirement for running the legacy ComServer.
This behaviour is visible when there are multiple parallel requests comming from the same client. When multiple requests come from different clients however, the behaviour changes:
Action 3 causes the ComServer to sometimes fail, causing COMExceptions.
Although the issue is probably caused by bad design of the COMObject, I cannot change this. The only thing I can do is surrounding COMObject access with an Application Lock
Dim oComSvr as object
oComSvr=Server.CreateObject("com_svr.my_svr")
...
Application.Lock
returnValue=oComSvr.selectform(value1, value2, ...)
Application.Unlock
However this prevents most COMExceptions, there are still specific timings that result in a COMException.
What can I do to force constant STA behaviour, also if multiple requests to the same IIS server come from different clients.
Tried to follow this article and implemented Page_Load to prevent the object being created before STA mode. http://technet.microsoft.com/en-ca/zwk9h2kb(v=vs.95).aspx
It still looks like if AspCompat is being ignored.
[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
Update: Read here and here that it is important WHERE the STA object is instantiated. Instantiating the object during construction time will cause this issue. http://technet.microsoft.com/en-ca/zwk9h2kb(v=vs.95).aspx http://msdn.microsoft.com/en-us/library/5dws599a(vs.71).aspx
Tried instantiating in Page_Load as in the example. However this does not change the behaviour when accessing the page from another client.
OK we've had this and this is how I've found a solution.. In our case I think it was linked to parent paths but could have been session state too...
Browse to C:\\Documents and Settings\\$your user name$\\My Documents\\IIS 7.5\\config
Open applicationHost.config
Find the section
Change the section to the following… By default it only had the cache and empty limits bits but feel free to adjust any parameters you don't want.
<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>
Save and restart iis 7.5.
if it is surrounding COMObject access with an Application Lock
However, if you write something like this in a sample format to get an idea.
Application["Counter"] = (int) Application["Counter"] + 1;
then you will need to use Lock and Unlock as follows:
Application.Lock();
Application["Counter"] = (int) Application["Counter"] + 1;
Application.Unlock();
This is because the thread might be interrupted between the read from, and then write to, the Application object, and another thread could therefore alter the value stored for the "Counter".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.