Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Network Variable Construction Time

Doing some dabbling with the new Network Variables - very cool. I like the fact that the variable engine is installed as a service, and I also like that if a network variable becomes disconnected from the server, it will intelligently reconnect when the server comes back online and proceed as expected.

One issue though: in the event that a network variable tries to connect to a variable manager that isn't started, or is on a rebooting machine, the connect call will fail with an exception. It will not automatically try and reconnect. So, the user must make sure the network variable successfully gets connected. I tried something like this:

while(true)
 {
    try
    {
        writer.Connect();
    }
    catch {}


    Thread.Sleep(2000);
    if (writer.ConnectionStatus == ConnectionStatus.Connected)
        break;
}

Although this works, everytime the writer.Connect call get executed, I notice a huge CPU spike - something within the connect call is taking a massive amount of resources, and bogs the system down until the connect call returns. I profiled the application and narrowed it down to this:

Int32 NationalInstruments.NetworkVariable.Internal.f.CNVCreateBufferedWriter*(String, e, m, IntPtr, Int32, Int32, Int32, ac &) - 10 calls to that took 24 seconds on a 3.8 ghz pentium 4

If I was only using one network variable, this might be ok, but I'm looking to convert all my apps over from DataSocket and in some I have 30-40 data sockets. In the event that the variable engine wasn't running, the app would be ground to a halt.

Is this a known issue? Is there any workaround?

Thanks,

Shea
0 Kudos
Message 1 of 4
(3,741 Views)
I am not seeing the huge CPU spike (very minimal CPU). I am also seeing the Connect call block for about a second (much less than you were seeing). I have a comparable machine, but am probably making assumptions about your code. Here is mine:
 
public partial class Form1 : Form
    {
        private NetworkVariableBufferedWriter<object> _writer;
        public Form1()
        {
            InitializeComponent();
            _writer = new NetworkVariableBufferedWriter<object>(@"\\fakelocation");
        }
        private void button1_Click(object sender, EventArgs e)
        {
            while (true)
            {
                try
                {
                    _writer.Connect();
                }
                catch (TimeoutException)
                {
                    Debug.WriteLine("Connect timed out.");
                }
                catch (NetworkVariableException ex)
                {
                    Debug.WriteLine(String.Format("Error Code = {0}, Message = {1}", ex.ErrorCode, ex.Message));
                }

                Thread.Sleep(2000);
                if (_writer.ConnectionStatus == ConnectionStatus.Connected)
                    break;
            }
        }
    }
 
Also notice that there are error codes and a description that are returned as properties of the exception. This will give you more information as to why the connect call failed. In general, the Connect method can be expensive. Maybe a ping call to the server would be more appropriate?
0 Kudos
Message 2 of 4
(3,716 Views)

Thanks for the reply.

I cut and pasted the code you provided into a new Windows app and experienced the same behaviour as before. I created a "demo" showing the effect of the program on my system (CPU pegged for 1-1.5 seconds on each Connect()) call - is there an email address I can send this demo? It's about 3 megs.

A successful ping prior to connect might be an option - but I find it difficult to believe that creation of a network connection requires billions of operations... it seems more likely that the cpu is needlessly spinning... are we sure there isn't a tight loop within the constructor call that would benefit from a Thread.Sleep(100)?

Another caveat that I noticed is that the intrinsic time stamp that comes in on data reads is off by 5 hours (for example, if the local time is 2pm, the timestamp coming in will be 7pm... I'm GMT-5 hours, probably not a coincidence). Oddly, the network variable manager shows the correct time stamp on the data passing through.

Cheers,

Shea

0 Kudos
Message 3 of 4
(3,708 Views)

The timestamp on the Data is Coordinated Universal Time (UTC) via the documentation. You can use DateTime.ToLocalTime() to convert to local time.

As far as the Connect() issue, I would try setting a smaller timeout when connecting. For example, Connect(TimeSpan.FromSeconds(1)). This might keep the function from blocking too long. By default the timeout is 10 seconds. So if you just call Connect(void) the timeout is taken to be 10 seconds.

Obviously, Connect() is taking ~2 seconds for you, so the long timeout is not coming into play because the function is finding out the variable doesn't exist before 10 seconds. A smaller timeout might expedite the function. However, this is a slipperly slope because if you have too small a timeout the function won't succeed even if the variable exists!

0 Kudos
Message 4 of 4
(3,704 Views)