예제 #1
0
        /// <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");
            }
        }
예제 #2
0
        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);
                }
            }
        }