X++ Compiled to .NET CIL Overview Lesson 1: Generating CIL Lesson 2: How Process Works Lesson 3: Debugging CIL Code Lesson 4: Scenarios Not supported Lab: Code Sample
Overview Why Is X++ Compiled to CIL? The CLR can execute code faster than the AX kernel in the following cases: 1. Computationally intensive code that does not do a lot of database access 2. Memory intensive code where lots of object are built and stored in memory
Overview In Microsoft Dynamics AX 2012 X++ batch jobs, service classes, and code executed on the AOS calling the RunAs API are compiled into the common intermediate language (CIL or simply IL) of the .NET framework. You can run your X++ code as CIL by using the method Global::runClassMethodIL. Using "server" modifier in your methods or setting RunOn Server parameter wont make it run as IL necessarily. The compilation creates an assembly called Dynamics.Ax.Application.dll which is stored on each AOS in the C:Program FilesMicrosoft Dynamics AX60ServerMicrosoftDynamicsAXbinXppIL folder. The .NET CLR executes the code rather than the AX kernel.
Overview RPC Services AOS • RunAs() • Batch Jobs • Services DB
Lesson 1: Generating CILThis lesson outlines the steps to turn X++ code into generated CIL code CIL Generation Steps Step Description 1. Write, save and compile your X++ class. The X++ source code for your class is automatically compiled into p-code when you save your source in the AOT. 2. Compile the p-code into CIL X++ is compiled into .NET CIL code. 3. Restart your multiple AOS services. If your installation has more than one AOS, you need to restart every AOS service after the CIL build completes. The recycle causes each AOS to load the assembly that contains the updated CIL. 4. Call the class. Schedule the batch job that executes your class or call the service class.
Lesson 1: Generating CILThis lesson outlines the steps to turn X++ code into generated CIL code CIL Compilation Options For step #2 on the previous slide, Compile the p-code into CIL, two options are available: 1. Generate Full CIL This option goes through the AOT and generates the CIL for all the modified objects that will be used in batch processes or as service classes. 2. Generate Incremental CIL This option causes the CIL to be generated for all objects that have been modified since the last time the assembly was generated.
Lesson 1: Generating CILThis lesson outlines the steps to turn X++ code into generated CIL code Generating CIL Code in the Developer Workspace Right-click the AOT node of the AOT, and navigate to the Add-Ins menu. The last two options on the menu will allow you to select the desired CIL option: You can also use the Build menu:
Lesson 1: Generating CILThis lesson outlines the steps to turn X++ code into generated CIL code Generating CIL Code in the Application Workspace As the Administrator navigate to the System administration menu in Microsoft Dynamics AX, and then under Periodic, choose ‘Compile into .NET Framework CIL’: Important: This does a Full CIL generation.
Lesson 1: Generating CILThis lesson outlines the steps to turn X++ code into generated CIL code Restart AOS Instances Step #3 in the CIL Generation Process is restart your multiple AOS services. After the assembly containing the CIL code has been created, the AOS used for the CIL generation has the current version of the assembly. However, other AOS have outdated code. To resolve this, the other AOS have to be restarted.
Lesson 2: How Process WorksThis lesson explains the process to compile and execute CIL code Create and compile Objects created in Microsoft Dynamics AX 2012 are stored in the "metadata store". In prior versions of Microsoft Dynamics AX, this information was stored in the *.AOD files. In Microsoft Dynamics AX 2012, the metadata store has been moved into SQL Server. X++ compiler examines the object information in the metadata store and generates the p-code for that object. When the object is needed, the p-code is then executed by the X++ interpreter. When the CIL generation is done, the Microsoft Dynamics AX generates an XML file that contains a representation of the code based on the metadata for the object, and the p-code that exists for that same object. The IL generator will generate an assembly and a *.PDB file from the XML.
Lesson 2: How Process WorksThis lesson explains the process to compile and execute CIL code CIL Generation X++ PCode . PDB DLL
Lesson 2: How Process WorksThis lesson explains the process to compile and execute CIL code Netmodules and FileSystem If a single class changes, only the module that contains it needs to change while all the other types remain untouched. Microsoft Dynamics AX 2012 uses an algorithm that is based on the object type that is used to determine the ID number value for each netmodule. In the file system, the assembly will be represented as one dll file and thousands of netmodules files:
Lesson 2: How Process WorksThis lesson explains the process to compile and execute CIL code Moving Databases between Environments The assembly containing the CIL code is stored in the database, and the version of the assembly in the database will be restored to the system if the database and file system versions are different. This is an attention point when updating the development environment with another database, like client production/homolog database.
Lesson 3: Debugging CIL CodeThis lesson explains how to debug the .NET CIL code created by Dynamics AX Requirements for Debugging To debug CIL code the AOS must have Debugging enabled via the Server configuration utility. If debugging on the AOS is not enabled, the source for the X++ code that will be displayed in the debugger is not available, and an error is displayed in Visual Studio when you attempt to view the X++ source code for an object. Visual Studio 2010 (VS) must be installed on the AOS. To debug CIL code you have to attach to the AX32Serv.exe process in Visual Studio. This is not possible if Visual Studio is not installed on the AOS.
Lesson 3: Debugging CIL CodeThis lesson explains how to debug the .NET CIL code created by Dynamics AX How to Debug CIL Code 1. On the AOS in VS click Tools, and then click Attach to Process. 2. In the form that opens mark the checkboxes for Show processes from all users and Show processes in all sessions. 3. Select AX32Serv.exe. 4. Click Attach. 5. In VS open the Application Explorer and locate the class or method you want to debug. The Application Explorer is simply a read only representation of the AOT, you navigate as you would the AOT in Microsoft Dynamics AX. 6. Set a breakpoint in the method. 7. Execute the batch process or call the service class. When the execution arrives at the breakpoint, the Visual Studio debugger provides all the functionality that it does for all other .NET languages.
Lesson 3: Debugging CIL CodeThis lesson explains how to debug the .NET CIL code created by Dynamics AX VS Attach to Process - Screen Example
Lesson 3: Debugging CIL CodeThis lesson explains how to debug the .NET CIL code created by Dynamics AX VS Debugging AX Class - Screen Example
Lesson 4: Scenarios Not SupportedThis lesson explains where we cant use CIL code Scenarios not supported and restrictions Functions There are two X++ functions not supported in CIL: evalbuf and runbuf. Incremental CIL Generation Restriction Remove a method: a full generation of CIL for the class is necessary to remove the method from the existing CIL. Compile outcome when a class has one bad method The X++ compiler still generates valid p-code for methods that contain no errors, even after another method on the same class has been failed to compile. But when a full compile of X++ p-code to CIL is performed, the entire compile fails if valid p-code is unavailable for any method on any class. Until your system has a successful full CIL compile, your system cannot run services, SSRS reports, or batch jobs.
Lesson 4: Scenarios Not SupportedThis lesson explains where we cant use CIL code Methods on Queries and Forms Class and tables are types in the X++ language. They can be compiled to CIL. The queries and forms in the AOT are not X++ types, and they cannot be compiled to CIL. This means there are a few minor cases where calls from CIL to X++ p-code can cause an exception. The problem is that the CIL session does not have access to all the system classes.
Lab: Code SampleThis lab shows two samples to illustrate CIL vs Pcode execution In this example we will use a simple condition to check if the active session is a CLR Session or not, called direct and by runClassMethodIL. 1. Create a class with main() and an additional method: 2. Generate Incremental CIL, and execute the class. Result:
Lab: Code SampleThis lab shows two samples to illustrate CIL vs Pcode execution In this example we will use a counter to show that the CIL run completed much faster than the interpreted run. 1. First, create a class (named DemoClassCIL) with main() and 3 additional methods:
Lab: Code SampleThis lab shows two samples to illustrate CIL vs Pcode execution
Lab: Code SampleThis lab shows two examples to illustrate CIL vs Pcode execution Generate Incremental IL and execute the class. The result is something like below: As seen above, the result in this example was about 40x faster when executed in CIL.