NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

.NET DLL call gets interrupted, EXE does not

Solved!
Go to solution

I have a strange problem. I am trying to create my own power supply ramp function because the supply I am using does not have one. I have a VB.NET dll that has a routine that just sets the voltage on the power supply in a loop to create my own ramp method. The ramp is displayed on an oscilloscope. It works fine and I get a nice smooth ramp except that sometimes I get choppiness or divets (for lack of a better term) in my ramp. It doesn't happen all the time but it is frequent enough that it's a big problem.

 

I had the problem in TestStand 4.2.1 but it was small enough that it was tolerable. I recently upgraded to TestStand 2010 SP1 and it is now worse. Bad enough that I can't accept it.

 

In trying to figure out what is going on and isolate the problem, I created an executable using VB.NET that calls my DLL and tests out the ramping. It works great. I get a nice smooth ramp. I then created a simple TestStand sequence that called the executable. Again, it works beautifully. I then used the Action step with the .NET adapter to call the method in the executable as if it were a DLL. (I didn't know you could do that but I stumbled on it.) Again, I get the divets in my ramp.

 

There appears to be something that TestStand is doing that interrupts my ramping method when it is called from a DLL using the Action step .NET adapter. So, does anybody know what TestStand is doing and how to stop it? I really don't what to have to turn all my steps into executable calls.

 

Thanks.

Message 1 of 13
(5,397 Views)

Can you try running with a non-.NET UI (e.g. MFC based) and see if the problem goes away? I suspect this is do to the sequence editor forcing garbage collection. If so, your best options currently would be to use a UI instead, or to run your code in an external process (you could use something like .NET remoting to allow for a rich API that you can still call into your code from the TestStand .NET Adapter with). Please let me know if running from a non-.NET UI works. This will help confirm whether or not garbage collection is the issue.

 

Hope this helps,

-Doug

Message 2 of 13
(5,376 Views)

I haven't tried running from a non-.NET UI except perhaps the TestStand Sequence Editor (I don't know what it's written in). That is where I was having the problem the most.

 

Thanks.

0 Kudos
Message 3 of 13
(5,373 Views)

Please try using the MFC UI and let me know if the problem goes away.

 

Thanks,

-Doug

0 Kudos
Message 4 of 13
(5,368 Views)

I tried the MFC UI that comes with TestStand. The problem goes away when using it. So, that does seem to point to garbage collection. I don't suppose you know how to disable garbage collection in .NET for a given chunk of code, do you?

 

Thanks.

0 Kudos
Message 5 of 13
(5,357 Views)
Solution
Accepted by Skeptical

Skeptical -

 

The Sequence Editor has a timer event that calls GC.Collect(). I've created an assembly that you can use to disable the GC.Collect() call performed in this timer event. Using this assembly, you only have to disable the GC.Collect() call once per instance of the Sequence Editor, but because disabling the periodic GC.Collect() call could result in other undesired behavior (e.g. execution of SequenceFileLoad/Unload callbacks may be delayed), I've written the assembly such that you can toggle whether the GC.Collect() call is enabled or disabled.

 

Attached you'll find a sequence file and assembly. In the attached sequence file, I've created two sequences, one for disabling the GC.Collect() call and one for enabling the GC.Collect() call. You can either use this assembly to disable the GC.Collect() call as soon as the Sequence Editor is launched (e.g. calling the assembly in FrontEndCallbacks) and leave it disabled for the lifetime of the Sequence Editor, or you can use the assembly to disable the GC.Collect() call prior to calling code modules that would benefit from it and then reenable the GC.Collect() call after your code modules have finished executing. Note that if you choose the latter approach, you will want to place some sort of delay after using the attached assembly to disable the GC.Collect() call but before calling your code modules, to ensure that any lingering garbage collection has completed.

 

Also note that using this assembly to disable the GC.Collect() call in the timer event does not mean that GC.Collect() will never be called again. The .NET Framework will force garbage collection if/when necessary. Finally, the most important caveat to note is that you can only use the attached assembly within the TestStand 2010 SP1 Sequence Editor (version 4.5.1.134). If you need this workaround for a different version of the Sequence Editor, let me know.

 

Let me know if you have questions about this workaround. Also, please reply to this post and confirm whether or not this workaround resolves the problem you were seeing in the Sequence Editor. Hope this helps!

Manooch H.
National Instruments
Message 6 of 13
(5,330 Views)

That helped significantly. However, we normally run using our own custom UI which as I am finding out has the same timer because NI recommends it. I get an error if I add steps to my sequence calling your assembly and then run it from my UI. But, I have added a means to my own UI to enable or disable the timer. Of course, if we are using the Sequence Editor to develop or debug we would still have the problem but I think that's okay at this point.

 

What isn't clear to me is why the problem is why the garbage collection seems to take longer with TestStand 2010 that it did with TestStand 4.21. But, we also switched from .NET 3.5 to .NET 4.0 so the problem could lie with that.

 

Thanks for your help.

0 Kudos
Message 7 of 13
(5,240 Views)

The speed of garbage collection is proportional to the number of managed objects that are currently allocated. If you have a leak in your code you will likely see garbage collection taking longer and longer over time. It's still possible to have leaks with garbage collection, it's just a bit more subtle because something has to be holding onto a object somewhere. Often a forgotten event handler is the source of a leak, holding an object which is holding another object which is holding another object and so forth. Or if you are just allocating more managed objects because you need to, it will take longer than it did before.

 

Hope this helps,

-Doug

0 Kudos
Message 8 of 13
(5,236 Views)

Hi, Manooch.

 

Good day.

 

I also have the similar problem

Can you please kindly help to create a sequence file for version 4.5.0.310.?

 

Thanks in advanced.

0 Kudos
Message 9 of 13
(4,936 Views)

For those needing to control garbage collection behavior in TestStand 2012 (5.0) and higher, there is a new API, Engine.DotNetGarbageCollectionInterval that you can use to adjust or disable the garbage collection interval.

 

Though this is probably not useful to you since you are using 4.5, it might be useful to someone else reading this thread.

 

Manooch or someone else will perhaps be able to help you with 4.5.

 

-Doug

0 Kudos
Message 10 of 13
(4,930 Views)