/// <summary> /// Acquires a writer lock for this record. /// </summary> /// <param name="dataModelTransaction">The transaction context for this operation.</param> //[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public virtual void AcquireWriterLock(IDataModelTransaction dataModelTransaction) { global::System.Guid transactionId = dataModelTransaction.TransactionId; try { global::System.Threading.Monitor.Enter(this.rowRoot); this.writerWaiters = (this.writerWaiters + 1); if ((this.writer != transactionId)) { int index = this._readers.BinarySearch(transactionId); if ((index >= 0)) { this._readers.RemoveAt(index); if (EventLog.IsLoggingEnabledFor(EventLog.ErrorLogLevel.Verbose)) { this._readersStackTrace.RemoveAt(index); } } for ( ; ((this.writer != global::System.Guid.Empty) || (this._readers.Count != 0)); ) { try { try { global::System.Threading.Monitor.Enter(this.writerRoot); global::System.Threading.Monitor.Exit(this.rowRoot); if (false == global::System.Threading.Monitor.Wait(this.writerRoot, this.LockTimeout)) { try { EventLog.Information("AcquireWriterLock TIMEOUT\r\n {0} Current Stack: {1} \r\n{2}", this.GetRowDebugDescription(), UnhandledExceptionHelper.GetStackString(), this.GetCurrentLockStacks(false)); } catch { } throw new FluidTrade.Core.Utilities.DeadlockException("AcquireWriterLock TIMEOUT", null); } } finally { global::System.Threading.Monitor.Exit(this.writerRoot); } } finally { global::System.Threading.Monitor.Enter(this.rowRoot); } } this.writer = transactionId; } } finally { this.writerWaiters = (this.writerWaiters - 1); global::System.Threading.Monitor.Exit(this.rowRoot); } dataModelTransaction.AddLock(this); if ((this.RowState == global::System.Data.DataRowState.Detached)) { throw new global::System.Exception("The " + this.GetType().FullName + " record was deleted after it was locked"); } }
private void LoadUnsafe() { // This flag is set when an error occurs anywhere in the processing of the XML file. this.HasErrors = false; // Read the XML data from the specified file. if (NotifyMessage != null) { this.NotifyMessage(this, new MessageEventArgs(string.Format("Loading {0}", FileName))); } XDocument xDocument = XDocument.Load(this.FileName); if (NotifyMessage != null) { this.NotifyMessage(this, new MessageEventArgs("Processing")); } // The script name is stored in the root node. The name is used in status and debugging messages. XAttribute nameAttribute = xDocument.Root.Attribute("name"); this.ScriptName = nameAttribute == null ? "Unnamed Transaction" : nameAttribute.Value; // This will force the user interface to appear the next time a channel is opened. It also releases any threads that // may have been waiting for the user to provide a set of credentials. Threads enter this waiting state when the user // hits the 'Cancel' button on any screen that prompts for credentials. if (this.ForceLogin && this.LocalMode == false) { ChannelStatus.IsPrompted = true; } if (this.LocalMode == false) { ChannelStatus.LoginEvent.Set(); } List <XElement> xElementList = new List <XElement>(); foreach (XElement xElement in xDocument.Root.Elements()) { xElementList.Add(xElement); } //default to be 10% int tickPercent = xElementList.Count / 10; if (tickPercent < 50) { tickPercent = 50; } else if (tickPercent > 1000) { tickPercent = 1000; } // Cycle through all of the children of the root node. Transactions are executed as a unit. Methods outside of a // transaction element are executed alone. for (int elementIndex = 0; elementIndex < xElementList.Count; elementIndex++) { XElement xElement = xElementList[elementIndex]; try { if (NotifyMessage != null && elementIndex % tickPercent == 0) { MessageEventArgs mea = new MessageEventArgs("Next Tick"); mea.IsProgressTick = true; this.NotifyMessage(this, mea); } switch (xElement.Name.LocalName) { case "client": // A channel is required for each endpont that will be contacted during his load. CreateClient(xElement); break; case "method": if (this.tranactionScopeStack.Count == 0) { using (TransactionScope transactionScope = new TransactionScope()) { // Parse and execute a single method out of the script. if (ExecuteMethod(xElement)) { this.MethodCount++; } transactionScope.Complete(); } } else { // Parse and execute a single method out of the script. if (ExecuteMethod(xElement)) { this.MethodCount++; } } break; case "transaction": // This creates a collection of methods that are executed as a unit. ExecuteTransaction(xElement); break; } } catch (Exception exception) { EventLog.Error(string.Format("{0} {1} {2}", exception.Message, exception.ToString(), exception.StackTrace)); ScriptLoaderException slEx = new ScriptLoaderException("Error in " + this.FileName, exception, xElement, this.MethodCount); if (NotifyMessage != null) { this.NotifyMessage(this, new MessageEventArgs(slEx.Message)); } throw slEx; } } if (NotifyMessage != null) { this.NotifyMessage(this, new MessageEventArgs(string.Format("Processed {0} methods in file: {1}", MethodCount, Path.GetFileName(FileName)))); } // One or more channels may have been created dynamicall from the information in the scripts. These dynamic channels // should be shut down gracefully before exiting. if (this.LocalMode == false) { foreach (KeyValuePair <String, ClientChannel> clientPair in this.clientTable) { MethodInfo closeMethod = clientPair.Value.ChannelType.GetMethod("Close"); closeMethod.Invoke(clientPair.Value.ChannelObject, null); } } }