/// <summary> /// Must be called before any COM call. /// </summary> /// <typeparam name="T">The interface to used when making the call.</typeparam> /// <param name="parent">Parent COM object</param> /// <param name="methodName">Name of the method.</param> /// <param name="isRequiredInterface">if set to <c>true</c> interface is an required interface and and exception is thrown on error.</param> /// <returns></returns> protected T BeginComCall <T>(object parent, string methodName, bool isRequiredInterface) where T : class { Utils.Trace(Utils.TraceMasks.ExternalSystem, "{0} called.", methodName); lock (lock_) { outstandingCalls_++; if (parent == null) { if (isRequiredInterface) { throw new NotConnectedException(); } } T comObject = parent as T; if (comObject == null) { if (isRequiredInterface) { throw new NotSupportedException(Utils.Format("OPC Interface '{0}' is a required interface but not supported by the server.", typeof(T).Name)); } else { Utils.Trace(Utils.TraceMasks.ExternalSystem, "OPC Interface '{0}' is not supported by server but it is only an optional one.", typeof(T).Name); } } DCOMCallWatchdog.Set(); return(comObject); } }
/// <summary> /// Must be called in the finally block after making a COM call. /// </summary> /// <param name="methodName">Name of the method.</param> protected void EndComCall(string methodName) { Utils.Trace(Utils.TraceMasks.ExternalSystem, "{0} completed.", methodName); lock (lock_) { outstandingCalls_--; DCOMCallWatchdog.Reset(); } }
/// <summary> /// Disables ability to cancel synchronous calls to the server /// </summary> public void DisableDCOMCallCancellation() { DCOMCallWatchdog.Disable(); }
/// <summary> /// Allows for cancellation of DCOM interface method calls to the server. By default DCOM interface calls will wait the default DCOM timeout /// to fail - this method allows for tighter control of the timeout to wait before cancelling the call. This is most useful during connect or any operation /// where it is not practical to wait 1+ minute(s) for the DCOM call to fail. Note that DCOM calls can only be controlled on a COM Single Threaded Apartment thread - /// use the [STAThread] attribute on your application entry point or use Thread SetThreadApartment before the thread the server is operating on is created to STA. /// </summary> /// <param name="timeout">The synchronous call timeout</param> public void EnableDCOMCallCancellation(TimeSpan timeout = default) { DCOMCallWatchdog.Enable(timeout); }