Solved

c# pass object by reference, wrapped TCP socket

Posted on 2016-08-01
6
74 Views
Last Modified: 2016-08-02
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?
0
Comment
Question by:jetbet
  • 3
  • 2
6 Comments
 
LVL 35

Expert Comment

by:Miguel Oz
Comment Utility
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.
0
 

Author Comment

by:jetbet
Comment Utility
I originally did not use the ref keyword and experienced the same issue.

I have removed it again but the problem remains.
0
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
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
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:jetbet
Comment Utility
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
0
 
LVL 32

Accepted Solution

by:
sarabande earned 500 total points
Comment Utility
The problem is that there should be just one and each object needs a reference to it.
with
requestStream = new RequestStream(jeqiReference.GetAddress(), jeqiReference.GetPort());

Open in new window

you create a new object and the old one is not deleted if there are still references to it. same applies for the Raceday object. if you want to have  singletons for those objects, you have to create them only once (with new) and then update the existing objects rather than to creating new ones. for example you could create temporarily new objects and 'assign' the new objects to the singletons.

Sara
0
 

Author Closing Comment

by:jetbet
Comment Utility
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
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Creating an OSPF network that automatically (dynamically) reroutes network traffic over other connections to prevent network downtime.
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now