in a customization job, I make use of 2 different Arrays of Struct, like
Array = new Array(types::Class);
Array2 = new Array(types::Class);
Array.value(id, new Struct(types::real, "param1", types::Integer, "param2"));
Array2.value(id, new Struct(types::string, "param3", types::Integer, "param4"));
first array holds in real 23 values in the struct (23 seems to be the limit in Struct)
So thats why I created a 2nd Array, cause I have more values.
What I experience is that after making a modification and start the code again, some values of the Struct are old values.
It looks like the Structs are not fully cleaned or initialized in memory.
Is this a memory leak?
Is finalize() the way to fix this, if yes how to use finalize exactly?
What can be the problem of this behaviour?
Why are you using Struct at all, especially if you're saying that it doesn't meet your requirements?
If you have a bunch of named values, why don't you design a class for that? If you don't know them at design time, you can use a Map object to hold name-value pairs.
Well.......because I know how to handle struct.
And am not into design classes.
I get the concept of classes, but to design from zero is not my cup of tea (yet)
Could you ls give me a headstart with a class for a bunch of value pairs?
It's a critical piece of knowledge - object-oriented programming (OOP) is all about objects (= instances of classes), therefore understanding them is crucial. If you don't know the basics, you simply must go and learn them. Fortunately internet is full of great resources.
Also realize that it's nothing specific to AX and AX resources won't teach you OOP. But that's not a problem; you can learn concepts from books written for other languages (e.g. I got the basics from Thinking in Java).
When you need something specific to AX, you can consult documentation. I would also highly recommend downloading and reading Inside Dynamics AX 4.0 (it's free!). Yes, it's for a newer version, but many things are the same and you'll learn a lot from it.
Now to the actual implementation. The class will be very simple - it will have several variables in ClassDesclaration, holding the values. Such as:
But these variables can't be accessed by other classes, therefore you need methods allowing to read and modify values from outside.
For each variable, you could write a "get" method returning the current value and a "set" method changing it, but the usual approach in AX is combining it to a single "parm" method. Like this:
public str parmName(str _name = name)
name = _name;
When you have that, you can create an instance of your class and use the methods to manipulate values. Because methods has meaningful names, it's easy to understand what's going on:
MyClass o = new MyClass();
Now that I'm busy with it.
Should I continue with Array = new Array(types::Class);
And then call Array.value(_id, o.parmname());
Or is there a way to initialize several instances of this same class, and identify those classes by an _id.
I think it should be possible, but where can I find an example of how this is done.
Can you please explain what you're trying to achieve? Ideally start with telling us a bit about the business requirement you're dealing with. Then it should be clearer what the technical solution needs to cover.
Of course you can create any number of instances of the same class. Like this:
MyClass c1 = new MyClass();
MyClass c2 = new MyClass();
You can put them into an array if you want, but I don't see any reason why you would put individual fields into an array. It looks like you stick to the wrong code that you designed before learning about classes. Again, an explanation of what you're doing would give me a better idea.
Thanks Martin, I will explain:
I want to track values of Commodoties like Oil, electricity and gas.
So it looks like, simplified
Commodity id open high low close valuenow
Oil 1 74.95 78.02 73.00 74.06 73.02
Gas 2 150.34 155 150.34 154.75 154.01
Electricity 3 34.09 44.6 32.00 40.25 40.10
I want to keep track of this in memory, cause database is too slow and variables are much easier.
I want to make decisions based on these prices.
So far I made something for it in an array as you know.
When initializing an external API I give the id during initializing.
So I get prices back, identified by the id and want to keep track of those.
So far I made a matrix with the nested arrays, and later array of structs.
As per your suggestion of creating a class, which is good idea cause I have much more possibilities.
But now stumble upon identify those classes.
So normally it would be myClass.open(74.95)
But am looking for something like
Where of course (1) (2) and (3) are the id's
You can design the classes like this, for example:
CommodityPrice oilPrice = new CommodityPrice();
CommodityPrice gasPrice = new CommodityPrice();
Of course, there are other options, such as putting the Type to the constructor:
CommodityPrice oilPrice = new CommodityPrice(CommodityType::Oil);
I don't have enough information about the entity to know which design would be the best.
If you want to put the prices to a collection and access them by their indexes, you can use Array, but you put there the whole objects and not individual values.
// Constructing the array
Array pricesArray = new Array(Types::Class);
// Getting a value
CommodityPrice price = pricesArray.value(2);
real openPrice = price.parmOpen();
Note that you can also use a table. If you want to keep things in memory, simply use a temporary table. And if you need to persist the data, a table is exactly the right thing.
You claim that using tables is complicated, but it's not the case. Take a look:
// Writing to a table
oilPrice.Type = CommodityType::Gas;
oilPrice.Id = 1;
oilPrice.Open = 74.95;
// Retrieving the data
select price where price.Id == 1;
real openPrice = price.Open;
Thanks again Martin, I admire your patience around this forum to explain every question in a patience way :)
I get the first part, but the end is a big eyeopener, and might be thé solution.
You say a tempTable is a table only processed in memory??
Well that would be perfect then. The knowledge of working with tables is quite good, so that would be perfect.
I don't want to use database, because its (too) slow and something in me thinks that's not good to write read 24/7, many,many times per second the same values..at the same place. I wonder if the HDD will like that. I can be wrong there, but mainly the speed is the most important factor
So with tempTable I have the speed of memory, and the easyness of tables. perfect match!
Thinking about that, I can make a class of that table and create methods which will populate that data.
I will start a new thread about that cause it got not much todo with the original question. See you there? ;)
Temporary tables in AX 3 are indeed held in memory, but only if you don't put much data there (128 KB, to be precise). If you do, it will be stored in a file on disk. Note that a temporary table may exist on either client or server (depending on where you insert the first record) and you should pay attention to it - you want to store the data on the tier where you'll need them.
But note that database are designed for storing a huge amount of data, efficient querying, running 24/7, for save concurrent access of many users, ensuring data consistency even in case of failure and so on. Don't try to build a kind of database in the application layer; you won't do it better than what huge teams of smart people designed, developed and improved for years. Using some local cache may be a good approach, but saying that you won't use a database server because it's slow and not good for concurrency doesn't make a good sense to me.
I strongly recommend that you read a bit about temporary tables before writing code. If you open Inside Microsoft Dynamics AX 4.0 (I gave you a link above), you'll find the section about temporary starting at page 351.