Solved

c# pass object by reference, wrapped TCP socket

Posted on 2016-08-01
6
127 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 36

Expert Comment

by:Miguel Oz
ID: 41738432
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
ID: 41738465
I originally did not use the ref keyword and experienced the same issue.

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

Expert Comment

by:sarabande
ID: 41738532
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:jetbet
ID: 41738597
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 34

Accepted Solution

by:
sarabande earned 500 total points
ID: 41738881
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
ID: 41739732
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

Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Sometimes clients can lose connectivity with the Lotus Notes Domino Server, but there's not always an obvious answer as to why it happens.   Read this article to follow one of the first experiences I had with Lotus Notes on a client's machine, my…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

726 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