Ending .NET component from the NAS

rspruitrspruit Member Posts: 25
The NAS starts a codeunit that in its turn starts a .NET 1.1 component that listens to a port for incomming ip network messages from another computer. When that computer connects, a new thread is launched to handle communication, the main process keeps on listening.

When there is an error message in Navision, the NAS "restarts" (in the event viewer I see the database, company, startupparameter, etc.) but it seems that the .NET component is still running, keeping the connection with the other computer alive. The new instance of the .NET component sees that the log file it opens is allready in use and the port it wants to listen to is allready listened by the old process.

The codeunit is of course a singleinstance. I create a timer automation var in it, in the OnRun I check with NOT ISCLEAR if it is created, if so I do an exit, if isclear then I start the .NET component. So getting these errors, it seems that the codeunit has been "cleared" but the .NET component not. What can I do to make the .NET component close itself so it can free the log file and the listening to the port?

Thanks in advance,

Remco

Answers

  • dick11dick11 Member Posts: 60
    I have made such a solution too and it works. But NAS never restarts because the errors are send to the event
    "Timer::TimerError(ErrorString : Text[1024])".
    And there I do the error handling.

    If you send me your email address I will send you my codeunit.
    email: dick@dasautomatisering.nl
    Dick van der Sar

    www.dasautomatisering.nl
  • Luc_VanDyckLuc_VanDyck Member, Moderator, Administrator Posts: 3,633
    If you submit it to the site, it can be made available for others too.
    No support using PM or e-mail - Please use this forum. BC TechDays 2024: 13 & 14 June 2024, Antwerp (Belgium)
  • rspruitrspruit Member Posts: 25
    Hi Dick, thanks for your reply. I've sent you my e-mail address. With your permission I will publish the code concerning this problem?

    The NAS does not truly restart, but my codeunit is apparently "gone" (the timer object is cleared so there must be a new instance of the singleinstance codeunit) and is run again. The reason I thought of this morning is that a .NET object is not destroyed when its application environment still exists and although there are probably no references to it, it keeps on logging and listening. Maybe what you do in the timer::timererror is telling the .NET object to dispose itself?
  • kinekine Member Posts: 12,562
    You can try to use
      Create(myAutomation,false);
    

    where the 2nd parameter means
    NewServer

    Data type: boolean

    If NewServer is FALSE (the default), CREATE will try to reuse an already running instance of the automation server referenced by Automation before creating a new instance. If NewServer is TRUE, CREATE will always create a new instance of the automation server.

    False is default, but you newer knows... #-o
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • rspruitrspruit Member Posts: 25
    I looked into the solution of Dick (thanks again for your time), but that does not cover my issue. A normal error stops the current thing the NAS does, but the timer trigger saves it all and keeps it going.

    The type of error my problem is about is in case of a locked table. If a user locks a table/record that the NAS process also wants to lock then, after the lock timeout, the singleinstance codeunit is completely gone. See the following screendump:

    - 10:08:43: The Communicatie Interface table cannot be changed because it is locked by another user.
    10:08:43:
    10:08:43: Wait until the user is finished and then try again.
    - 10:08:44: The Navision Application Server nav-sql recovered using the following configuration and is now fully operational.
    10:08:44: Database Server Name = IND04\SQLEXPRESS
    10:08:44: Database = Ontw20070102
    10:08:44: Company = Ontw20070122
    10:08:44: Startup Parameter = COMDEV

    The .NET component stays in memory and keeps running, because nassql.exe does not stop. There are 2 ways to deal with this I think:
    1) Let the .NET component write in the database (probably causing more locks!)
    2) The .NET component has to free its resources (port and log file)

    Option 2 is my favorite. I'll check out some .NET forums, maybe they can help. I'll let you know!
  • kinekine Member Posts: 12,562
    May be that the problem is that this is not total stop of the service but just "recovering". It means default transaction is ended and some objects are released from memory. In which object you defined the Automation? May be you can use another singleinstance than the one which is "interrupted" by the error.
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • rspruitrspruit Member Posts: 25
    kine wrote:
    May be that the problem is that this is not total stop of the service but just "recovering". It means default transaction is ended and some objects are released from memory. In which object you defined the Automation? May be you can use another singleinstance than the one which is "interrupted" by the error.

    I created the .NET component in codeunit X and did a "bad thing" in codeunit Y (both singleinstance). The result is the same, the NAS gets rid of both codeunits and recovers as mentioned above.
  • rspruitrspruit Member Posts: 25
    I added a Dispose method (inherit IDisposable) to the .NET client. It got called indeed, but at the actual termination of the NAS, not at recovery time... :-(

    Next thing I'm going to try is to run the .NET component from a VB 6.0 ActiveX DLL. I made a small test COM component and the destructor fires when the NAS recovers, so there I could call a cleanup function in the .NET component and shut down the listening and close the log file.

    To be continued....

    PS : anyone experienced with a .NET component call in VB6? The existing .NET component I can add as a reference, but I cannot see the functions and properties when programming...
  • kinekine Member Posts: 12,562
    rspruit wrote:
    PS : anyone experienced with a .NET component call in VB6? The existing .NET component I can add as a reference, but I cannot see the functions and properties when programming...

    On this forum there are threads about creating Automations from VS2005 and what is needed to do to see the functions from NAV.

    http://www.mibuso.com/forum/viewtopic.php?t=14377
    http://www.mibuso.com/forum/viewtopic.p ... c&start=30
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • rspruitrspruit Member Posts: 25
    I can now use the .NET component in VB6 (I declared the variable with Dim myVar As MyNetComp instead of Dim MyVar As MyNetComp.MyNetComp...).

    My status up till now: A VB6 component's destructor fires when the NAS is going down to recover. In the desctructor code I will tell the .NET comp to stop listening/logging. The .NET component will stay in memory, but harmless, the GC will cleanup sometime.

    Keep u posted!
  • rspruitrspruit Member Posts: 25
    Ok, now I have a working version. As planned I made a COM component that creates the .NET component and acts as a wrapper for all its functions and properties. In the destructor of the COM component I call a function in the .NET component that stops the listening to the port, aborts the communication thread and closes the log file.

    It took me a while because I had to abort some threads and they block on tcpListener.AcceptTcpClient() and NetworkStream.Read(). I had to use the tcpListener.Pending() and NetWorkStream.DataAvailable() functions before to get the threads to abort.
Sign In or Register to comment.