void FindStaticMethods(TypePlan typeplan) { max_staticMethodParCount = 0; List <MethodPlan> allStaticCreateMethods = new List <MethodPlan>(); List <MethodPlan> plans = typeplan.methods; int j = plans.Count; for (int i = 0; i < j; ++i) { MethodPlan m = plans[i]; if (m.metDecl.IsStatic) { allStaticCreateMethods.Add(m); if (m.pars.Count > max_staticMethodParCount) { max_staticMethodParCount = m.pars.Count; } } } if (allStaticCreateMethods.Count == 0) { this.staticMethods = null; } else { this.staticMethods = allStaticCreateMethods; } }
void GenerateCppImplNamespace(CodeTypeDeclaration orgDecl, List <MethodPlan> callToDotNetMets, CodeStringBuilder stbuilder) { string namespaceName = orgDecl.Name + "Ext"; //namespace this.CppImplClassNameId = _typePlan.CsInterOpTypeNameId; this.CppImplClassName = namespaceName; //---------------------------------------------- //create a cpp namespace stbuilder.Append("namespace " + namespaceName); stbuilder.AppendLine("{"); int nn = callToDotNetMets.Count; for (int mm = 0; mm < nn; ++mm) { //implement on event notificationi MethodPlan met = callToDotNetMets[mm]; met.CppMethodSwitchCaseName = namespaceName + "_" + met.Name + "_" + (mm + 1); } nn = callToDotNetMets.Count; for (int mm = 0; mm < nn; ++mm) { //implement on event notificationi MethodPlan met = callToDotNetMets[mm]; //prepare data and call the callback GenerateCppImplMethodForNs(met, stbuilder); } stbuilder.AppendLine("}"); //---------------------------------------------- //---------------------------------------------- //InternalHeaderForExportFunc.h _cppHeaderInternalForExportFuncAuto.AppendLine("namespace " + namespaceName); _cppHeaderInternalForExportFuncAuto.AppendLine("{"); _cppHeaderInternalForExportFuncAuto.AppendLine("const int _typeName=" + "CefTypeName_" + orgDecl.Name + ";"); for (int mm = 0; mm < nn; ++mm) { MethodPlan met = callToDotNetMets[mm]; _cppHeaderInternalForExportFuncAuto.AppendLine("const int " + met.CppMethodSwitchCaseName + "=" + (mm + 1) + ";"); } _cppHeaderInternalForExportFuncAuto.AppendLine("}"); //---------------------------------------------- //ExportFuncAuto.h _cppHeaderExportFuncAuto.AppendLine("namespace " + namespaceName); _cppHeaderExportFuncAuto.AppendLine("{"); for (int mm = 0; mm < nn; ++mm) { //implement on event notificationi MethodPlan met = callToDotNetMets[mm]; //prepare data and call the callback GenerateCppImplMethodDeclarationForNs(met, _cppHeaderExportFuncAuto); } _cppHeaderExportFuncAuto.AppendLine("}"); }
void GenerateCppImplMethodDeclarationForNs(MethodPlan met, CodeStringBuilder stbuilder) { CodeMethodDeclaration metDecl = met.metDecl; stbuilder.AppendLine("//CefHandlerTx::GenerateCppImplMethodDeclarationForNs ," + (++codeGenNum)); stbuilder.AppendLine("//gen! " + metDecl.ToString()); //--------------------------- //temp switch (metDecl.ReturnType.ToString()) { case "FilterStatus": stbuilder.Append(metDecl.ReturnType.ResolvedType + " " + metDecl.Name + "("); break; case "ReturnValue": string ownerType = met.metDecl.OwnerTypeDecl.Name; stbuilder.Append(ownerType + "::" + metDecl.ReturnType + " " + metDecl.Name + "("); break; default: stbuilder.Append(metDecl.ReturnType + " " + metDecl.Name + "("); break; } List <CodeMethodParameter> pars = metDecl.Parameters; //first par is managed callback stbuilder.Append("managed_callback mcallback"); int j = pars.Count; for (int i = 0; i < j; ++i) { stbuilder.Append(","); CodeMethodParameter par = pars[i]; if (par.IsConstPar) { stbuilder.Append("const "); } //parameter type stbuilder.Append(par.ParameterType.ResolvedType.FullName + " "); stbuilder.Append(par.ParameterName); } stbuilder.AppendLine(");"); }
public override void GenerateCode(CefCodeGenOutput output) { CodeTypeDeclaration orgDecl = this.OriginalDecl; CodeTypeDeclaration implTypeDecl = this.ImplTypeDecl; GenerateCppCode(output._cppCode); GenerateCsCode(output._csCode); //----------------------------------------------------------- string namespaceName = orgDecl.Name + "Ext"; CodeStringBuilder const_methodNames = new CodeStringBuilder(); CppToCsMethodArgsClassGen cppMetArgClassGen = new CppToCsMethodArgsClassGen(); // CodeStringBuilder cppArgClassStBuilder = new CodeStringBuilder(); cppArgClassStBuilder.AppendLine("namespace " + orgDecl.Name + "Ext{"); int j = _typePlan.methods.Count; for (int i = 0; i < j; ++i) { MethodPlan met = _typePlan.methods[i]; cppMetArgClassGen.GenerateCppMethodArgsClass(met, cppArgClassStBuilder); const_methodNames.AppendLine("const int " + namespaceName + "_" + met.Name + "_" + (i + 1) + "=" + (i + 1) + ";"); } cppArgClassStBuilder.AppendLine("}"); //---------------------------------------------- output._cppHeaderExportFuncAuto.Append(cppArgClassStBuilder.ToString()); //---------------------------------------------- //InternalHeaderForExportFunc.h CodeStringBuilder internalHeader = output._cppHeaderInternalForExportFuncAuto; internalHeader.AppendLine("namespace " + namespaceName); internalHeader.AppendLine("{"); internalHeader.AppendLine("const int _typeName=" + "CefTypeName_" + orgDecl.Name + ";"); internalHeader.AppendLine(const_methodNames.ToString()); internalHeader.AppendLine("}"); //---------------------------------------------- }
/// <summary> /// Creates a method plan from the parameters listed. /// </summary> /// <param name="methodNode">An XML node where the method and parameters are found.</param> private MethodPlan LoadMethod(XmlNode methodNode) { // Create a new method from the type information and the name found in the XML file. MethodPlan method = new MethodPlan(methodNode.Attributes["name"].Value); // Load each of the parameters into the method structure. foreach (XmlNode parameterNode in methodNode.ChildNodes) { // Ignore Comment Nodes. if (parameterNode.NodeType == XmlNodeType.Comment) { continue; } // Add the next parameter to the method. method.Parameters.Add(new InputParameter(parameterNode.Name, parameterNode.InnerText == string.Empty ? (object)DBNull.Value : (object)parameterNode.InnerText)); } // Return the method plan created from the script. return(method); }
static int Main(string[] args) { // If this flag is set during the processing of the file, the program will exit with an error code. bool hasErrors = false; try { // Defaults batchSize = 100; assemblyName = "External Service"; nameSpaceName = "MarkThree.Quasar.External"; // The command line parser is driven by different states that are triggered by the flags read. Unless a flag has been // read, the command line parser assumes that it's reading the file name from the command line. argumentState = ArgumentState.FileName; // Parse the command line for arguments. foreach (string argument in args) { // Decode the current argument into a state change (or some other action). if (argument == "-a") { argumentState = ArgumentState.Assembly; continue; } if (argument == "-b") { argumentState = ArgumentState.BatchSize; continue; } if (argument == "-n") { argumentState = ArgumentState.NameSpace; continue; } if (argument == "-i") { argumentState = ArgumentState.FileName; continue; } // The parsing state will determine which variable is read next. switch (argumentState) { case ArgumentState.Assembly: assemblyName = argument; break; case ArgumentState.BatchSize: batchSize = Convert.ToInt32(argument); break; case ArgumentState.FileName: fileName = argument; break; case ArgumentState.NameSpace: nameSpaceName = argument; break; } // The default state is to look for the input file name on the command line. argumentState = ArgumentState.FileName; } // Throw a usage message back at the user if no file name was given. if (fileName == null) { throw new Exception("Usage: Loader.Algorithm -i <FileName>"); } // Open up the file containing all the broker. BrokerReader brokerReader = new BrokerReader(fileName); // Loading the database involves creating a batch of commands and sending them off as a transaction. This gives // the server a chance to pipeline a large chunk of processing, without completely locking up the server for the // entire set of data. This will construct a header for the command batch which gives information about which // assembly contains the class that is used to load the data. Batch batch = new Batch(); TransactionPlan transactionPlan = batch.Transactions.Add(); AssemblyPlan assemblyPlan = batch.Assemblies.Add(assemblyName); TypePlan typePlan = assemblyPlan.Types.Add(string.Format("{0}.{1}", nameSpaceName, "Broker")); // Read the file until an EOF is reached. while (true) { // This counter keeps track of the number of records sent. When the batch is full, it's sent to the server to be // executed as a single transaction. int batchCounter = 0; // Read the next broker from the input stream. A 'null' is returned when we've read past the end of file. Broker broker = brokerReader.ReadBroker(); if (broker != null) { // Create a new method from the type information and the name found in the XML file. MethodPlan methodPlan = new MethodPlan("Load"); // Construct a call to the 'Load' method to populate the broker record. methodPlan.Parameters.Add(new InputParameter("brokerId", broker.Symbol)); methodPlan.Parameters.Add(new InputParameter("name", broker.Name)); methodPlan.Parameters.Add(new InputParameter("symbol", broker.Symbol)); // Create a method from the XML data and add it to the transaction. transactionPlan.Methods.Add(typePlan, methodPlan); } // This will check to see if it's time to send the batch. A batch is sent when the 'batchSize' has been // reached, or if the last record has just been converted into a command. if (++batchCounter % batchSize == 0 || broker == null) { WebTransactionProtocol.Execute(batch); batch = new Batch(); transactionPlan = batch.Transactions.Add(); assemblyPlan = batch.Assemblies.Add(assemblyName); typePlan = assemblyPlan.Types.Add(string.Format("{0}.{1}", nameSpaceName, "Broker")); } // If the end of file was reached, break out of the loop and exit the application. if (broker == null) { break; } } } catch (BatchException batchException) { foreach (Exception exception in batchException.Exceptions) { Console.WriteLine(exception.Message); } hasErrors = true; } catch (Exception exception) { // Show the system error and exit with an error. Console.WriteLine(exception.Message); hasErrors = true; } // Any errors will cause an abnormal exit. if (hasErrors) { return(1); } // Write a status message when a the file is loaded successfully. Console.WriteLine(String.Format("{0} Data: Brokers, Loaded", DateTime.Now.ToString("u"))); // If we reached here, the file was imported without issue. return(0); }
/// <summary> /// Begins the task of applying the changes in the form to the data model. /// </summary> private void PostThread(object parameter) { // Extract the parameters from the threads parameter. object[] parameters = (object[])parameter; bool exitDialog = (bool)parameters[0]; SourceOrder sourceOrder = (SourceOrder)parameters[1]; // This batch will collect the information needed to execute a complex transaction on the server. The first part of // the batch sets up the transaction: the assembly where the types and methods are found. It also sets up a // transaction for a complex operation. In this case, the transaction is not that complex, just a single method to be // executed. Batch batch = new Batch(); AssemblyPlan assembly = batch.Assemblies.Add("Trading Service"); TypePlan type = assembly.Types.Add("MarkThree.Guardian.Trading.SourceOrder"); TransactionPlan transaction = batch.Transactions.Add(); MethodPlan methodPlan = transaction.Methods.Add(type, "Insert"); // These are the parameters used to create a Source Order. The Working Order will be created implicitly. methodPlan.Parameters.Add(new InputParameter("blotterId", this.blotter.BlotterId)); methodPlan.Parameters.Add(new InputParameter("isBrokerMatch", sourceOrder.IsBrokerMatch)); methodPlan.Parameters.Add(new InputParameter("isHedgeMatch", sourceOrder.IsHedgeMatch)); methodPlan.Parameters.Add(new InputParameter("isInstitutionMatch", sourceOrder.IsInstitutionMatch)); methodPlan.Parameters.Add(new InputParameter("submissionTypeCode", SubmissionType.UsePeferences)); if (sourceOrder.MaximumVolatility != DBNull.Value) { methodPlan.Parameters.Add(new InputParameter("maximumVolatility", sourceOrder.MaximumVolatility)); } if (sourceOrder.NewsFreeTime != DBNull.Value) { methodPlan.Parameters.Add(new InputParameter("newsFreeTime", sourceOrder.NewsFreeTime)); } methodPlan.Parameters.Add(new InputParameter("orderedQuantity", sourceOrder.Quantity)); methodPlan.Parameters.Add(new InputParameter("orderTypeCode", sourceOrder.OrderTypeCode)); methodPlan.Parameters.Add(new InputParameter("priceTypeCode", PriceType.Market)); methodPlan.Parameters.Add(new InputParameter("securityId", sourceOrder.SecurityId)); methodPlan.Parameters.Add(new InputParameter("settlementId", sourceOrder.SettlementId)); if (sourceOrder.StartTime != DBNull.Value) { methodPlan.Parameters.Add(new InputParameter("startTime", sourceOrder.StartTime)); } if (sourceOrder.StopTime != DBNull.Value) { methodPlan.Parameters.Add(new InputParameter("stopTime", sourceOrder.StopTime)); } methodPlan.Parameters.Add(new InputParameter("timeInForceCode", TimeInForce.Day)); // This will execute the command on the server and return any exceptions. BatchException batchException = null; try { // Execute the batch. ClientMarketData.Execute(batch); } catch (BatchException exception) { // Any exceptions will be captured here and passed on to the foreground. batchException = exception; } // Call the foreground thread with the results of executing the batch on the server. Also, in some cases the dialog is // going to be dismissed when the server data model has finished updating successfully. Pass on the flag to the // foreground that will indicate whether the form is closed once the results are processed. BeginInvoke(this.postEndDelegate, new object[] { exitDialog, batchException }); }
private void DeclineTrade(object parameter) { bool isBatchValid = true; Batch batch = new Batch(); MethodPlan method = null; try { // Lock the tables. System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.MatchLock.AcquireReaderLock(ClientTimeout.LockWait); ClientMarketData.OrderTypeLock.AcquireReaderLock(ClientTimeout.LockWait); ClientMarketData.SecurityLock.AcquireReaderLock(ClientTimeout.LockWait); ClientMarketData.WorkingOrderLock.AcquireReaderLock(ClientTimeout.LockWait); // Find the Match record. ClientMarketData.MatchRow matchRow = ClientMarketData.Match.FindByMatchId(this.matchId); AssemblyPlan assembly = batch.Assemblies.Add("Core Service"); TypePlan type = assembly.Types.Add("MarkThree.Guardian.Core.Negotiation"); TransactionPlan transaction = batch.Transactions.Add(); method = transaction.Methods.Add(type, "Insert"); method.Parameters.Add(new InputParameter("matchId", matchId)); method.Parameters.Add(new InputParameter("quantity", 0.0m)); method.Parameters.Add(new InputParameter("statusCode", Status.Declined)); } catch (Exception exception) { // Write the error and stack trace out to the debug listener EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); // This indicates that the batch shouldn't be executed. isBatchValid = false; } finally { // Release the locks. if (ClientMarketData.MatchLock.IsReaderLockHeld) { ClientMarketData.MatchLock.ReleaseReaderLock(); } if (ClientMarketData.OrderTypeLock.IsReaderLockHeld) { ClientMarketData.OrderTypeLock.ReleaseReaderLock(); } if (ClientMarketData.SecurityLock.IsReaderLockHeld) { ClientMarketData.SecurityLock.ReleaseReaderLock(); } if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld) { ClientMarketData.WorkingOrderLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } // If the command batch was built successfully, then execute it. If any part of it should fail, cancel the edit and // display the server errors. if (isBatchValid) { try { // Call the web server to rename the object on the database. Note that this method must be called when there // are no locks to prevent deadlocking. That is why it appears in it's own 'try/catch' block. ClientMarketData.Execute(batch); this.negotiationId = (int)method.Parameters.Return.Value; } catch (BatchException batchException) { // Display each error in the batch. foreach (Exception exception in batchException.Exceptions) { Invoke(new MessageDelegate(ShowMessage), exception.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }
/// <summary> /// Moves a child object from one parent to another. /// </summary> /// <param name="parameter">An array consiting of the target parent, the current parent and the child to be moved.</param> private void MoveChild(object parameter) { // Extract the objects selected by the drag-and-drop operation. object[] parameters = (object[])parameter; MarkThree.Guardian.Object toObject = (MarkThree.Guardian.Object)parameters[0]; MarkThree.Guardian.Object fromObject = (MarkThree.Guardian.Object)parameters[1]; MarkThree.Guardian.Object childObject = (MarkThree.Guardian.Object)parameters[2]; try { // Lock the tables needed for this operation. System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ObjectTreeLock.AcquireReaderLock(CommonTimeout.LockWait); // It's critical that circular references aren't created, either by accident or design. First, find the object // record associated with the destination node. ClientMarketData.ObjectRow parentRow = ClientMarketData.Object.FindByObjectId(toObject.ObjectId); if (parentRow == null) { throw new Exception("This object has been deleted"); } // This is the object that is being dragged. Find the row ClientMarketData.ObjectRow childRow = ClientMarketData.Object.FindByObjectId(childObject.ObjectId); if (childRow == null) { throw new Exception("This object has been deleted"); } // This will remove the possibility of a circular relationship. if (MarkThree.Guardian.Relationship.IsChildObject(childRow, parentRow)) { Invoke(new MessageDelegate(ShowMessage), Properties.Resources.CircularReferenceError, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } catch (Exception exception) { // Write the error and stack trace out to the debug listener EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); } finally { // Release table locks. if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } if (ClientMarketData.ObjectTreeLock.IsReaderLockHeld) { ClientMarketData.ObjectTreeLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } // Any commands created below will be constructed in this object and sent to the server for execution. bool isBatchValid = true; Batch batch = new Batch(); // If we made it here, the drag-and-drop is interpreted as a command to move a child from one parent to another. try { // Lock the tables needed for this operation. System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ObjectTreeLock.AcquireReaderLock(CommonTimeout.LockWait); // Extract the primary identifiers from the user interface nodes. // This is the object that is being dragged. Find the row ClientMarketData.ObjectRow childRow = ClientMarketData.Object.FindByObjectId(childObject.ObjectId); if (childRow == null) { throw new Exception("This object has been deleted"); } // Find the object in the data model and make sure it still exists. ClientMarketData.ObjectTreeRow objectTreeRow = null; foreach (ClientMarketData.ObjectTreeRow innerObjectTreeRow in childRow.GetObjectTreeRowsByObjectObjectTreeChildId()) { if (innerObjectTreeRow.ParentId == fromObject.ObjectId) { objectTreeRow = innerObjectTreeRow; } } if (objectTreeRow == null) { throw new Exception("This relationship has been deleted by someone else."); } // Moving a child object from one parent to another must be accomplished as a transaction. Otherwise, an // orhpan object will be created if the operation fails midway through. TransactionPlan transaction = batch.Transactions.Add(); AssemblyPlan assembly = batch.Assemblies.Add("Core Service"); TypePlan type = assembly.Types.Add("MarkThree.Guardian.Core.ObjectTree"); // Construct a command delete the old parent relation. MethodPlan deleteObjectTree = transaction.Methods.Add(type, "Update"); deleteObjectTree.Parameters.Add(new InputParameter("objectTreeId", objectTreeRow.ObjectTreeId)); deleteObjectTree.Parameters.Add(new InputParameter("parentId", toObject.ObjectId)); deleteObjectTree.Parameters.Add(new InputParameter("childId", childObject.ObjectId)); deleteObjectTree.Parameters.Add(new InputParameter("rowVersion", objectTreeRow.RowVersion)); } catch (Exception exception) { // Write the error and stack trace out to the debug listener EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); // This indicates that the batch shouldn't be executed. isBatchValid = false; } finally { // Release table locks. if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } if (ClientMarketData.ObjectTreeLock.IsReaderLockHeld) { ClientMarketData.ObjectTreeLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } // If the command batch was built successfully, then execute it. if (isBatchValid) { try { // Call the web server to rename the object on the database. Note that this method must be called when there are // no locks to prevent deadlocking. That is why it appears in it's own 'try/catch' block. ClientMarketData.Execute(batch); } catch (BatchException batchException) { // Display each error in the batch. foreach (Exception exception in batchException.Exceptions) { MessageBox.Show(exception.Message, "Guardian Error"); } } } }
/// <summary> /// Rename the object. /// </summary> /// <param name="parameters">The object to be renamed.</param> private void RenameObject(object parameter) { // Extract the thread arguments object[] parameters = (object[])parameter; TreeNode treeNode = (TreeNode)parameters[0]; string name = (string)parameters[1]; // Extract the object that is associated with the TreeView node. MarkThree.Guardian.Object commonObject = (MarkThree.Guardian.Object)treeNode.Tag; // This command batch is constructed below and sent to the server for execution. Note that the batch is designed to // live beyond the block of code that locks the data model. This is to prevent the data model from being locked while // a relatively long server database operation is underway. bool isBatchValid = true; Batch batch = new Batch(); try { // Lock the table System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); // Find the object in the data model and make sure it still exists. ClientMarketData.ObjectRow objectRow = ClientMarketData.Object.FindByObjectId(commonObject.ObjectId); if (objectRow == null) { throw new Exception("This object has been deleted."); } // Construct a command to rename the object. AssemblyPlan assembly = batch.Assemblies.Add("Core Service"); TypePlan type = assembly.Types.Add("MarkThree.Guardian.Core.Object"); TransactionPlan transaction = batch.Transactions.Add(); MethodPlan method = transaction.Methods.Add(type, "Update"); method.Parameters.Add(new InputParameter("rowVersion", objectRow.RowVersion)); method.Parameters.Add(new InputParameter("objectId", objectRow.ObjectId)); method.Parameters.Add(new InputParameter("name", name)); } catch (Exception exception) { // This serves as an indication that the batch couldn't be constructed. isBatchValid = false; // Write the error and stack trace out to the debug listener EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); } finally { // Release table locks. if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } // If the command batch was built successfully, then execute it. If any part of it should fail, cancel the edit and // display the server errors. if (isBatchValid) { try { // Call the web server to rename the object on the database. Note that this method must be called when there // are no locks to prevent deadlocking. That is why it appears in it's own 'try/catch' block. ClientMarketData.Execute(batch); } catch (BatchException batchException) { // Display each error in the batch. foreach (Exception exception in batchException.Exceptions) { Invoke(new MessageDelegate(ShowMessage), exception.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }
/// <summary> /// Execute a command batch and synchronizes the client data model with the newer records from the server. /// </summary> public static void Execute(Batch batch) { // This 'try' block will insure that the mutual exclusion locks are released. try { // Make sure only one thread at a time tries to refresh the data model. ClientMarketData.clientDataMutex.WaitOne(); // Switching credentials without exiting the application will force the data model to be cleared and the row // counting to begin at zero again. That is, it effectively resets the client data model. if (ClientMarketData.isReset) { ClientMarketData.isReset = false; ClientMarketData.rowVersion = 0; ClientMarketData.Clear(); } // IMPORTANT CONCEPT: The rowVersion keeps track of the state of the client in-memory database. The server // returns a value for us to use on the next cycle. long rowVersion = ClientMarketData.rowVersion; // IMPORTANT CONCEPT: Executing the 'GetClientMarketData' with a rowVersion returns to the client a DataSet // with only records that are the same age or younger than the rowVersion. This reduces the traffic on the // network to include only the essential records. We are also merging it with the current ClientMarketData, // which adds new records and records that were deleted by the server. AssemblyPlan assembly = batch.Assemblies.Add("Server Market Data"); TypePlan type = assembly.Types.Add("MarkThree.Guardian.Server.ServerMarketData"); TransactionPlan transaction = batch.Transactions.Add(); MethodPlan method = transaction.Methods.Add(type, "Reconcile"); Parameter rowVersionParameter = method.Parameters.Add(new InputParameter("rowVersion", rowVersion)); // Execute the the command to get the incremental changes from the server. WebTransactionProtocol.Execute(batch); // This is the updated data model information returned from the server. ArrayList reconciledData = (ArrayList)method.Parameters.Return.Value; // Optimization: Don't merge the results if there's nothing to merge. if (reconciledData != null) { // IMPORTANT CONCEPT: Since the results will still be on the server if the client misses a refresh // cycle, we take the attitude that thBzis update process doesn't have to wait for locks. That is, if we // can't get all the tables locked quickly, we'll just wait until the next refresh period to get the // results. This effectively prevents deadlocking on the client. Make sure all the tables are locked // before populating them. foreach (TableLock tableLock in ClientMarketData.TableLocks) { tableLock.AcquireWriterLock(ClientTimeout.LockWait); } // IMPORTANT CONCEPT: This broadcast can be used to set up conditions for the data event handlers. Often, // optimizing algorithms will be used to consolidate the results of a merge. This will allow the event // driven logic to clear previous results and set up initial states for handling the bulk update of data. ClientMarketData.OnBeginMerge(typeof(ClientMarketData)); // IMPORANT CONCEPT: Once all the write locks have been obtained, we can merge the results. This will // trigger the events associated with the tables for updated and deleted rows. Note that this 'Merge' // method has different characteristics than the original one provided by Microsoft (that is, this one // works). ClientMarketData.rowVersion = MarketData.Merge(reconciledData); // IMPORTANT CONCEPT: When the merge is complete, this will broadcast an event which allows optimization code // to consolidate the results, examine the changed values and update reports based on the changed data. ClientMarketData.OnEndMerge(typeof(ClientMarketData)); } } finally { // No matter what happens above, we need to release the locks acquired above. foreach (TableLock tableLock in ClientMarketData.TableLocks) { if (tableLock.IsWriterLockHeld) { tableLock.ReleaseWriterLock(); } } // Other threads can now request a refresh of the data model. ClientMarketData.clientDataMutex.ReleaseMutex(); } // Throw a specialized exception if the server returned any errors in the Batch structure. if (batch.HasExceptions) { throw new BatchException(batch); } }
void GenerateCppImplMethodForNs(MethodPlan met, CodeStringBuilder stbuilder) { CodeMethodDeclaration metDecl = met.metDecl; stbuilder.AppendLine("//CefHandlerTx::GenerateCppImplMethodForNs ," + (++codeGenNum)); stbuilder.AppendLine("//gen! " + metDecl.ToString()); //--------------------------- //temp if (metDecl.ReturnType.ToString() == "FilterStatus") { stbuilder.Append(metDecl.ReturnType.ResolvedType + " " + metDecl.Name + "("); } else if (metDecl.ReturnType.ToString() == "ReturnValue") { string ownerName = metDecl.OwnerTypeDecl.Name; stbuilder.Append(ownerName + "::" + metDecl.ReturnType + " " + metDecl.Name + "("); } else { stbuilder.Append(metDecl.ReturnType + " " + metDecl.Name + "("); } List <CodeMethodParameter> pars = metDecl.Parameters; int j = pars.Count; //transfer data slot bool hasSomeOutVars = false; CppTempParameterSlot[] dataTransferSlots = new CppTempParameterSlot[j]; for (int i = 0; i < j; ++i) { CppTempParameterSlot transferSlot = new CppTempParameterSlot(); CodeMethodParameter par = pars[i]; transferSlot.par = pars[i]; dataTransferSlots[i] = transferSlot; // // string parTypeName = par.ParameterType.ToString(); if (parTypeName == "CefRefPtr<CefV8Value>&") { if (!par.IsConstPar) { transferSlot.newVarName = "temp_" + i; transferSlot.preStmt = "auto " + transferSlot.newVarName + "=" + "CefV8ValueCToCpp::Unwrap(" + transferSlot.par.ParameterName + ");"; transferSlot.postStmt = transferSlot.par.ParameterName + "= CefV8ValueCToCpp::Wrap(" + transferSlot.newVarName + ");"; transferSlot.isCppOutVar = true; hasSomeOutVars = true; } } else if (parTypeName == "CefString&") { if (!par.IsConstPar) { transferSlot.newVarName = "temp_" + i; transferSlot.preStmt = "auto " + transferSlot.newVarName + "=" + transferSlot.par.ParameterName + ";"; transferSlot.postStmt = transferSlot.par.ParameterName + "=" + transferSlot.newVarName + ";"; transferSlot.isCppOutVar = true; hasSomeOutVars = true; } } } //first par is managed callback stbuilder.Append("managed_callback mcallback"); for (int i = 0; i < j; ++i) { stbuilder.Append(","); CodeMethodParameter par = pars[i]; if (par.IsConstPar) { stbuilder.Append("const "); } //parameter type stbuilder.Append(par.ParameterType.ResolvedType.FullName + " "); stbuilder.Append(par.ParameterName); } stbuilder.AppendLine("){"); //----------- for (int i = 0; i < j; ++i) { MethodParameter parTx = met.pars[i]; parTx.ClearExtractCode(); PrepareDataFromNativeToCs(parTx, "&vargs[" + (i + 1) + "]", parTx.Name, true); } //method body //----------------------------- //use native C data slot stbuilder.AppendLine("if(mcallback){"); //'out' vars if (hasSomeOutVars) { //temp, for (int i = 0; i < j; ++i) { CppTempParameterSlot transferSlot = dataTransferSlots[i]; if (transferSlot.isCppOutVar) { stbuilder.AppendLine(transferSlot.preStmt); } } } //----------------------------- // string metArgsClassName = metDecl.Name + "Args"; stbuilder.Append(metArgsClassName + " args1"); //with ctors if (j == 0) { stbuilder.AppendLine(";"); } else { stbuilder.Append("("); for (int i = 0; i < j; ++i) { if (i > 0) { stbuilder.Append(","); } // MethodParameter par = met.pars[i]; CppTempParameterSlot transferSlot = dataTransferSlots[i]; if (transferSlot.isCppOutVar) { stbuilder.Append("&" + transferSlot.newVarName); } else { //temp string parType = par.TypeSymbol.ToString(); if (parType.EndsWith("&")) { stbuilder.Append("&"); } stbuilder.Append(par.Name); } } stbuilder.AppendLine(");"); } stbuilder.AppendLine("mcallback( (_typeName << 16) | " + met.CppMethodSwitchCaseName + ",&args1.arg);"); //------ //'out' vars if (hasSomeOutVars) { //temp, for (int i = 0; i < j; ++i) { CppTempParameterSlot transferSlot = dataTransferSlots[i]; if (transferSlot.isCppOutVar) { stbuilder.AppendLine(transferSlot.postStmt); } } } //temp fix, arg extract code if (!met.ReturnPlan.IsVoid) { stbuilder.AppendLine("return args1.arg.myext_ret_value;"); } stbuilder.AppendLine("}"); //------------------- //default return if no managed callback if (!met.ReturnPlan.IsVoid) { string retTypeName = metDecl.ReturnType.ToString(); if (retTypeName.StartsWith("CefRefPtr<")) { stbuilder.Append("return nullptr;"); } else { switch (metDecl.ReturnType.ToString()) { case "bool": stbuilder.Append("return false;"); break; case "FilterStatus": //TODO: revisit here stbuilder.Append("return (FilterStatus)0;"); break; case "ReturnValue": { string ownerName = metDecl.OwnerTypeDecl.Name; stbuilder.Append("return (" + ownerName + "::ReturnValue)0;"); } break; case "CefSize": stbuilder.Append("return CefSize();"); break; case "size_t": stbuilder.Append("return 0;"); break; case "int": stbuilder.Append("return 0;"); break; case "int64": stbuilder.Append("return 0;"); break; default: throw new NotSupportedException(); } } } stbuilder.AppendLine("}"); //method }
void GenerateCppCode(CodeStringBuilder stbuilder) { #if DEBUG _dbug_cpp_count++; #endif // //create switch table for C#-interop // CodeTypeDeclaration orgDecl = this.OriginalDecl; CodeTypeDeclaration implTypeDecl = this.ImplTypeDecl; _typePlan = orgDecl.TypePlan; //----------------------------------------------------------------------- List <MethodPlan> onEventMethods = new List <MethodPlan>(); int j = _typePlan.methods.Count; int maxPar = 0; for (int i = 0; i < j; ++i) { MethodPlan metTx = _typePlan.methods[i]; if (metTx.metDecl.IsVirtual) { //this method need a callback to .net side (.net-side event listener) if (metTx.metDecl.Name.StartsWith("On")) { onEventMethods.Add(metTx); } } metTx.CppMethodSwitchCaseName = orgDecl.Name + "_" + metTx.Name + "_" + (i + 1); if (metTx.pars.Count > maxPar) { maxPar = metTx.pars.Count; } } MaxMethodParCount = maxPar; //---------- CppHandleCsMethodRequestCodeGen cppHandleCsMetCodeGen2 = new CppHandleCsMethodRequestCodeGen(); cppHandleCsMetCodeGen2.PrepareInstanceCallFromCppToCsMethodName( this, orgDecl, ImplTypeDecl, this.UnderlyingCType); // cppHandleCsMetCodeGen2.GenerateCppCode( this, orgDecl, ImplTypeDecl, this.UnderlyingCType, stbuilder ); //---------- if (onEventMethods.Count > 0) { //the callback need some method to call to C# side var eventListenerCodeGen = new CppEventListenerInstanceImplCodeGen(); eventListenerCodeGen.GenerateCppImplClass( this, _typePlan, orgDecl, onEventMethods, stbuilder); } }
/// <summary> /// Read, parse and load the stylesheet into the middle tier. /// </summary> public void Load() { // If this flag is set during the processing of the file, the program will exit with an error code. this.HasErrors = false; // If the user wants to specify a new URL and certificate, then prompt for the connection info the next time a // WebTransactionProtocol sends off a batch. if (this.ForceLogin) { WebTransactionProtocol.IsUrlPrompted = true; WebTransactionProtocol.IsCredentialPrompted = true; } // Load up an XML document with the contents of the file specified on the command line. XmlDocument stylesheet = new XmlDocument(); stylesheet.Load(this.FileName); // The XML document has several nodes that need to be read -- and then removed -- that contain attributes of the // stylesheet. These nodes can be found easily using the XSL Path functions which need a namespace manager to sort out // the tag prefixes. XmlNamespaceManager namespaceManager = new XmlNamespaceManager(stylesheet.NameTable); namespaceManager.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform"); namespaceManager.AddNamespace("mts", "urn:schemas-markthreesoftware-com:stylesheet"); // The spreadhseet source has several nodes which contain information about how the data in the XML document should be // loaded into the server, such as the stylesheet identifier, the name and the stylesheet style. They are found at // this node. After these information nodes have been read, they are removed from the stylesheet source. XmlNode stylesheetNode = stylesheet.SelectSingleNode("xsl:stylesheet", namespaceManager); if (stylesheetNode == null) { throw new Exception("Syntax Error: missing stylesheet declaration."); } // Find the StylesheetId node. XmlNode StylesheetIdNode = stylesheetNode.SelectSingleNode("mts:stylesheetId", namespaceManager); if (StylesheetIdNode == null) { throw new Exception("Syntax Error: missing StylesheetId declaration."); } // Find the StylesheetStyle node. XmlNode stylesheetTypeCodeNode = stylesheetNode.SelectSingleNode("mts:stylesheetTypeCode", namespaceManager); if (stylesheetTypeCodeNode == null) { throw new Exception("Syntax Error: missing StylesheetStyle declaration."); } // Find the name node. XmlNode nameNode = stylesheetNode.SelectSingleNode("mts:name", namespaceManager); if (nameNode == null) { throw new Exception("Syntax Error: missing name declaration."); } // Extract the data from the XML nodes. this.StylesheetId = StylesheetIdNode.InnerText; this.StylesheetTypeCode = stylesheetTypeCodeNode.InnerText; this.StylesheetName = nameNode.InnerText; // Remove the stylesheet nodes from the XSL spreadsheet before loading it into the server. stylesheetNode.RemoveChild(StylesheetIdNode); stylesheetNode.RemoveChild(stylesheetTypeCodeNode); stylesheetNode.RemoveChild(nameNode); // Create a command to load the stylesheet from the data loaded from the file. Batch batch = new Batch(); TransactionPlan transaction = batch.Transactions.Add(); AssemblyPlan assembly = batch.Assemblies.Add(this.Assembly); TypePlan type = assembly.Types.Add(this.Type); MethodPlan method = transaction.Methods.Add(type, this.Method); method.Parameters.Add(new InputParameter("stylesheetId", this.StylesheetId)); method.Parameters.Add(new InputParameter("stylesheetTypeCode", this.StylesheetTypeCode)); method.Parameters.Add(new InputParameter("name", this.StylesheetName)); method.Parameters.Add(new InputParameter("text", stylesheet.InnerXml)); try { // Create a new web client that will serve as the connection point to the server and call the web services to execute // the command batch. WebTransactionProtocol.Execute(batch); } catch (BatchException) { foreach (MethodPlan batchMethod in transaction.Methods) { foreach (Exception exception in batchMethod.Exceptions) { Console.WriteLine(String.Format("{0}: {1}", method.Parameters["StylesheetId"].Value, exception.Message)); } } this.HasErrors = true; } }
public override void GenerateCode(CefCodeGenOutput output) { _cppHeaderExportFuncAuto = output._cppHeaderExportFuncAuto; _cppHeaderInternalForExportFuncAuto = output._cppHeaderInternalForExportFuncAuto; //cpp CodeTypeDeclaration orgDecl = this.OriginalDecl; CodeTypeDeclaration implTypeDecl = this.ImplTypeDecl; CodeStringBuilder totalTypeMethod = new CodeStringBuilder(); if (implTypeDecl.Name.Contains("CppToC")) { _typePlan = orgDecl.TypePlan; } else { _typePlan = implTypeDecl.TypePlan; } //----------------------------------------------------------------------- List <MethodPlan> callToDotNetMets = new List <MethodPlan>(); CodeStringBuilder const_methodNames = new CodeStringBuilder(); int maxPar = 0; int j = _typePlan.methods.Count; for (int i = 0; i < j; ++i) { MethodPlan metTx = _typePlan.methods[i]; metTx.CppMethodSwitchCaseName = orgDecl.Name + "_" + metTx.Name + "_" + (i + 1); //----------------- CodeMethodDeclaration codeMethodDecl = metTx.metDecl; if (codeMethodDecl.IsAbstract || codeMethodDecl.IsVirtual) { callToDotNetMets.Add(metTx); } //----------------- if (metTx.pars.Count > maxPar) { maxPar = metTx.pars.Count; } const_methodNames.AppendLine("const int " + metTx.CppMethodSwitchCaseName + "=" + (i + 1) + ";"); } totalTypeMethod.AppendLine(const_methodNames.ToString()); //----------------------------------------------------------------------- if (callToDotNetMets.Count > 0) { GenerateCppImplNamespace(orgDecl, callToDotNetMets, output._cppCode); } //----------------------------------------------------------------------- //C# part CsStructModuleCodeGen structModuleCodeGen = new CsStructModuleCodeGen(); if (callToDotNetMets.Count > 0) { structModuleCodeGen.GenerateCsStructClass(orgDecl, callToDotNetMets, output._csCode, false); } //back to cpp again... CppToCsMethodArgsClassGen cppMetArgClassGen = new CppToCsMethodArgsClassGen(); //------------------------------------------------------------------ CodeStringBuilder cppArgClassStBuilder = new CodeStringBuilder(); cppArgClassStBuilder.AppendLine("namespace " + orgDecl.Name + "Ext{"); for (int i = 0; i < j; ++i) { MethodPlan met = _typePlan.methods[i]; cppMetArgClassGen.GenerateCppMethodArgsClass(met, cppArgClassStBuilder); } cppArgClassStBuilder.AppendLine("}"); _cppHeaderExportFuncAuto.Append(cppArgClassStBuilder.ToString()); //------------------------------------------------------------------ }
void GenerateCppCode(CodeStringBuilder stbuilder) { #if DEBUG _dbug_cpp_count++; #endif // //create switch table for C#-interop // CodeTypeDeclaration orgDecl = this.OriginalDecl; CodeTypeDeclaration implTypeDecl = this.ImplTypeDecl; TypePlan typeTxInfo = implTypeDecl.Name.Contains("CppToC") ? orgDecl.TypePlan : implTypeDecl.TypePlan; // FindStaticMethods(orgDecl.TypePlan); // CppHandleCsMethodRequestCodeGen cppHandlerReqCodeGen = new CppHandleCsMethodRequestCodeGen(); cppHandlerReqCodeGen.GenerateCppCode(this, orgDecl, implTypeDecl, this.UnderlyingCType, stbuilder); string namespaceName = orgDecl.Name + "Ext"; int j = cppHandlerReqCodeGen.callToDotNetMets.Count; if (j > 0) { CodeStringBuilder const_methodNames = new CodeStringBuilder(); //check if method has duplicate name or not //---------- Dictionary <string, MethodPlan> uniqueNames = new Dictionary <string, MethodPlan>(); foreach (MethodPlan met in cppHandlerReqCodeGen.callToDotNetMets) { MethodPlan existingMet; if (uniqueNames.TryGetValue(met.Name, out existingMet)) { string met_capi_name = FindCApiName(met.metDecl); string met_capi_nameOfExistingMet = FindCApiName(existingMet.metDecl); if (met_capi_nameOfExistingMet == null && met_capi_name == null) { throw new NotSupportedException(); } //rename both if possible existingMet.HasDuplicatedMethodName = true; if (met_capi_nameOfExistingMet != null) { existingMet.NewOverloadName = met_capi_nameOfExistingMet; } else { existingMet.NewOverloadName = existingMet.Name; } // met.HasDuplicatedMethodName = true; if (met_capi_name != null) { met.NewOverloadName = met_capi_name; } else { met.NewOverloadName = met.Name; } } else { uniqueNames.Add(met.Name, met); } } //----------------------- for (int i = 0; i < j; ++i) { MethodPlan met = cppHandlerReqCodeGen.callToDotNetMets[i]; if (met.HasDuplicatedMethodName) { const_methodNames.AppendLine("const int " + namespaceName + "_" + met.NewOverloadName + "_" + (i + 1) + "=" + (i + 1) + ";"); } else { const_methodNames.AppendLine("const int " + namespaceName + "_" + met.Name + "_" + (i + 1) + "=" + (i + 1) + ";"); } } //-------------- CppInstanceImplCodeGen instanceImplCodeGen = new CppInstanceImplCodeGen(); instanceImplCodeGen.GenerateCppImplClass(this, typeTxInfo, cppHandlerReqCodeGen.callToDotNetMets, orgDecl, stbuilder); cpp_callToDotNetMets = cppHandlerReqCodeGen.callToDotNetMets; //----------------------------------------------------------- CppToCsMethodArgsClassGen cppMetArgClassGen = new CppToCsMethodArgsClassGen(); // CodeStringBuilder cppArgClassStBuilder = new CodeStringBuilder(); cppArgClassStBuilder.AppendLine("namespace " + namespaceName + "{"); for (int i = 0; i < j; ++i) { MethodPlan met = cppHandlerReqCodeGen.callToDotNetMets[i]; cppMetArgClassGen.GenerateCppMethodArgsClass(met, cppArgClassStBuilder); } cppArgClassStBuilder.AppendLine("}"); //---------------------------------------------- _output._cppHeaderExportFuncAuto.Append(cppArgClassStBuilder.ToString()); //---------------------------------------------- //InternalHeaderForExportFunc.h CodeStringBuilder internalHeader = _output._cppHeaderInternalForExportFuncAuto; internalHeader.AppendLine("namespace " + namespaceName); internalHeader.AppendLine("{"); internalHeader.AppendLine("const int _typeName=" + "CefTypeName_" + orgDecl.Name + ";"); internalHeader.AppendLine(const_methodNames.ToString()); internalHeader.AppendLine("}"); //---------------------------------------------- } if (staticMethods != null) { CppHandleCsMethodRequestCodeGen cppHandlerReqCodeGen2 = new CppHandleCsMethodRequestCodeGen(); cppHandlerReqCodeGen2.GenerateCppCodeStatic(staticMethods, orgDecl, implTypeDecl, stbuilder); CodeStringBuilder const_methodNames = new CodeStringBuilder(); //check if method has duplicate name or not for (int i = 0; i < j; ++i) { MethodPlan met = cppHandlerReqCodeGen.callToDotNetMets[i]; const_methodNames.AppendLine("const int " + namespaceName + "_" + met.Name + "_" + (i + 1) + "=" + (i + 1) + ";"); } //create static method for cpp type //in this version we don't create an custom impl of the class //----------------------------------------------------------- CppToCsMethodArgsClassGen cppMetArgClassGen = new CppToCsMethodArgsClassGen(); // CodeStringBuilder cppArgClassStBuilder = new CodeStringBuilder(); cppArgClassStBuilder.AppendLine("namespace " + namespaceName + "{"); j = staticMethods.Count; for (int i = 0; i < j; ++i) { MethodPlan met = staticMethods[i]; cppMetArgClassGen.GenerateCppMethodArgsClass(met, cppArgClassStBuilder); } cppArgClassStBuilder.AppendLine("}"); //---------------------------------------------- //generate cpp class } }
/// <summary> /// Marshals the data needed refuse a chance to negotiate a trade. /// </summary> /// <param name="parameter">The thread initialization data.</param> private void DeclineNegotiationThread(object parameter) { // Extract the thread parameters int matchId = (int)parameter; // This batch, if succesfully constructed, will be sent to the server to deline the negotiation. Batch batch = new Batch(); try { // Lock the tables. System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.MatchLock.AcquireReaderLock(ClientTimeout.LockWait); ClientMarketData.OrderTypeLock.AcquireReaderLock(ClientTimeout.LockWait); ClientMarketData.SecurityLock.AcquireReaderLock(ClientTimeout.LockWait); ClientMarketData.WorkingOrderLock.AcquireReaderLock(ClientTimeout.LockWait); // Find the Match record. ClientMarketData.MatchRow matchRow = ClientMarketData.Match.FindByMatchId(matchId); // Construct a command decline the negotiation. AssemblyPlan assembly = batch.Assemblies.Add("Core Service"); TypePlan type = assembly.Types.Add("MarkThree.Guardian.Core.Negotiation"); TransactionPlan transaction = batch.Transactions.Add(); MethodPlan method = transaction.Methods.Add(type, "Insert"); method.Parameters.Add(new InputParameter("matchId", matchId)); method.Parameters.Add(new InputParameter("quantity", 0.0m)); method.Parameters.Add(new InputParameter("statusCode", Status.Declined)); } catch (Exception exception) { // Write the error and stack trace out to the debug listener EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); // This indicates that the batch shouldn't be executed. batch = null; } finally { // Release the locks. if (ClientMarketData.MatchLock.IsReaderLockHeld) { ClientMarketData.MatchLock.ReleaseReaderLock(); } if (ClientMarketData.OrderTypeLock.IsReaderLockHeld) { ClientMarketData.OrderTypeLock.ReleaseReaderLock(); } if (ClientMarketData.SecurityLock.IsReaderLockHeld) { ClientMarketData.SecurityLock.ReleaseReaderLock(); } if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld) { ClientMarketData.WorkingOrderLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } // If the command batch was built successfully, then execute it. if (batch != null) { try { // Call the web server to rename the object on the database. Note that this method must be called when there // are no locks to prevent deadlocking. That is why it appears in it's own 'try/catch' block. ClientMarketData.Execute(batch); } catch (BatchException batchException) { // Write any server generated error messages to the event log. foreach (Exception exception in batchException.Exceptions) { EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); } } } }