Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EMA C#: OmmDate object modified during the for-each iteration #291

Closed
y-intercept2018 opened this issue Nov 5, 2024 · 3 comments
Closed

Comments

@y-intercept2018
Copy link

y-intercept2018 commented Nov 5, 2024

Real-Time: For Real-Time SDK C#, looks like the OmmDate object will be modified during the for-each iteration. This strange behavior does not happen to all RICs, for example, it does not happen on RIC /0005.HK, it does happen on RIC /HCEIX4 .

public void OnRefreshMsg(RefreshMsg refreshMsg, IOmmConsumerEvent consumerEvent)
{
    OmmDate? date = null;
    Console.WriteLine(refreshMsg);
    foreach (var field in refreshMsg.Payload().FieldList())
    {
        if (field.Code == Data.DataCode.BLANK)
            continue;
        switch (field.FieldId){
            case 16:
                date = field.OmmDateValue();
                Console.WriteLine($"date (in-place): {date}");
                break;
        }

    }
    Console.WriteLine($"date (after-foreach): {date}");
}

This function is used to extract one specific field with fieldId == 16 (i.e., TRADE_DATE) into my date object. The output I get is this:
date (in-place): 29 OCT 2024
date (after-foreach): (blank data)

This issue was also discussed on a LSEG forum here and it seems to be a bug.

My environment:
DotNet 6.0 with LSEG.Ema.Core 3.3.0

@V-Anyakin
Copy link
Contributor

@y-intercept2018 Thank you for raising this issue and the information provided.

For performance reasons RTSDK EMA Library reuses objects whenever possible. That's why objects returned from data access methods are transient and short-lived. Values that they contain are not guaranteed to live outside of scope.

In the case described above it is application's responsibility to copy data it needs from the object returned by the OmmDataValue() method.

@y-intercept2018
Copy link
Author

Hi @V-Anyakin from a C++ point of view this explanation makes sense as in C/C++ we have the idea of ownership and enlightened C++ programers are required to understand the implication of referring to a non-owning object.

But in terms of C# this is very confusing as C# does not use the ownership concept to manage memory and users rely on reference counting (which is usually transparent to typical programmers). As long as users are still referring to an object, the expectation is that it will never be cleared. I believe this is also one of the major selling points of the "easier" languages such as Java and C#--lets not burden programmers with the complexity of C++ and in return they must tolerate the overheads of automatic GC.

Now you are bringing this back to C#, which is not ideal i would say.

Also seems the same issue does not occur on Java, why is there such a difference?

@V-Anyakin
Copy link
Contributor

Hello, @y-intercept2018

Decision to reuse class instances whenever possible instead of creating new objects on the heap was made because of performance considerations. This approach is followed across all three flavors, including Java.

However, the Java FieldList has two methods to access its contents: the greedy iterator() and the lazy iteratorByRef().

When accessed via iterator returned by the iterator() method (it is an implementation of the Collection.iterator() interface method), each entry is represented by a separate data instance. They are still pooled, and are reused, but together with the whole collection. See:

When accessed via iterator returned by the iteratorByRef() method, Java FieldList behaves the same way as the C# FieldList -- it uses a single FieldEntry instance to represent all underlying entries one by one. This approach is faster than the previous one. See:

@y-intercept2018 y-intercept2018 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants