Avatar of jetbet
jetbetFlag for New Zealand

asked on 

c# pass object by reference, wrapped TCP socket

I have an application that has a primary and secondary data source that it connects to. I create and update an object when the primary server  crashes so that all requests will be done on the secondary until it comes back up.
public class RequestStream
    {
        private TcpClient socket;
        private NetworkStream stream;
        private String address;
        private String port;

        public RequestStream(String aAddress, String aPort)
        {
            address = aAddress;
            port = aPort;
            try
            {
                socket = new TcpClient();
                socket.Connect(address, int.Parse(port));
                stream = socket.GetStream();
            }
            catch (Exception ex)
            {
               //
            }
        }

Open in new window

I have a separate thread that "heartbeats" the servers to check their status. When I need to change servers I trigger the following code situated on the DataStore object.
public void resetAllThreads()
        {
            try
            {
                lock (_locker)
                {
                    requestStream = new RequestStream(jeqiReference.GetAddress(), jeqiReference.GetPort());
                }
            }
            catch (Exception ex)
            {
               //
            }
        }

Open in new window

A breakpoint shows this is working correctly.

I pass a copy of the RequestStream to the constructor of an object called Raceday
requestStream = new RequestStream(jeqiReference.GetAddress(), jeqiReference.GetPort());

raceDay = new RaceDay(jeqiReference, ref requestStream);

Open in new window


The trouble is that the DataStore object correctly uses the new server but the Raceday object does not. On the Raceday object the adress stays the same but the stream is null. If I restart the Server and the object is updated again, the stream is now initiated again and works as before.

The Request stream object is passed through the raceday object to another set of objects, each of which again passes this through in other constructors.

How can I ensure the RequestStream in all the objects is the same object so this will work as intended?
C#TCP/IP.NET Programming

Avatar of undefined
Last Comment
jetbet
Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

Do not use parameter by reference. In your class ensure that Request stream object is passed by value:
public RaceDay (Whatever jeqiReference, RequestStream requestStream)
{//your code goes here}

Open in new window


When you are passing the object by value,  the value is a reference for reference types - a way of getting to the object (a pointer to memory location). The RaceDay class will not be able to change the stream object but only its public properties or whatever state is changed by public methods.
Avatar of jetbet
jetbet
Flag of New Zealand image

ASKER

I originally did not use the ref keyword and experienced the same issue.

I have removed it again but the problem remains.
Avatar of sarabande
sarabande
Flag of Luxembourg image

On the Raceday object the adress stays the same but the stream is null.
since you created a new RequestStream and a new Raceday object, the old RequestStream and old Raceday object are no longer valid and are subject of the garbage collector (gc). that means the Raceday objetc you were looking for is no longer the one which should be alive but needs to be replaced by the new one.

the gc might be able to do this granted that there are no references to the old objects which prevent the old objects to be released and granted that you provided destructors which properly release and close all their open resources.

with other words: the statement
raceDay = new RaceDay(jeqiReference, ref requestStream);

Open in new window

should release and clear old raceDay object.

Sara
Avatar of jetbet
jetbet
Flag of New Zealand image

ASKER

Sorry I did not explain well enough.

The DataStore contains a Raceday and these are not destroyed until the Application closes.

The issue is with the RequestStream object that is used by The DataCenter, Raceday, Meeting, etc. type objects.

This is updated as necessary when there are issues with one of the servers. The problem is that there should be just one and each object needs a reference to it.

Each object that contains a reference can use it to update its own state via new information contained in an XML request/response via TCP
ASKER CERTIFIED SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of jetbet
jetbet
Flag of New Zealand image

ASKER

That was it.
I had assumed that the link to the piece of memory where the RequestStream was stored would remain valid for the references.
Thanks for the help
.NET Programming
.NET Programming

The .NET Framework is not specific to any one programming language; rather, it includes a library of functions that allows developers to rapidly build applications. Several supported languages include C#, VB.NET, C++ or ASP.NET.

137K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo