cancel
Showing results for 
Search instead for 
Did you mean: 

Sap .Nco 3.0 connector, Connection not closed/Logoff

Former Member
0 Kudos

I am using Tuturiol downloaded from Connectors download link.

Connection created using RfcDestinationManager.GetDestination() is not closed.

I am calling method Test() on button click, in test1(). I am not able to close the connection by setting the desitination object to null even.

In SAP transaction SM04, session list still shows the RFC connection with 'myusername' after the call to the method test() is finished.

  • Connection is closed only when i close my windows application.

C# code

-



private void btnLogon_Click(object sender, EventArgs e)
{
  Test();
}

void Test()
{
RfcConfigParameters parameters = new RfcConfigParameters();

            parameters[RfcConfigParameters.Name] = "Test1";
            parameters[RfcConfigParameters.User] = "myusername";
            parameters[RfcConfigParameters.Password] = "mypassword";
            parameters[RfcConfigParameters.Client] = "800";
            parameters[RfcConfigParameters.Language] = "EN";
            parameters[RfcConfigParameters.AppServerHost] = "192.168.101.15";
            parameters[RfcConfigParameters.SystemNumber] = "00";

            RfcDestination destination = RfcDestinationManager.GetDestination(parameters);
            RfcSessionManager.BeginContext(destination);
            
            destination.Ping();
            IRfcFunction function = null;

            try
            {
             // read table from RFC            
              function = destination.Repository.CreateFunction("BDC_RECORD_TRANSACTION");
                IRfcTable obj1 = function.GetTable("DYNPROTAB");
            }
            catch (Exception ex)
            {
                          System.Windows.Forms.MessageBox.Show("Error: " + ex.Message);
            }
                       
            RfcSessionManager.EndContext(destination);
            destination  = null;
}

Edited by: HarminderSingh on Mar 10, 2011 6:14 AM

Accepted Solutions (0)

Answers (8)

Answers (8)

0 Kudos

Hi Markus,

In above code when  below line is getting executed it is throwing  null reference exception.

changeHandler(name, eventArgs);

Please help.

Regards,

Milan

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Milan,

there is nothing that could cause a NullReferenceException in this line? Are you sure it is this line?

Best regards,

Markus

0 Kudos

Surely can a NullException occur! As long as if no event handler is assigned, a call to `changeHandler` will throw a NullException. A better call would be

changeHandler?.Invoke(name, eventArgs);
Former Member
0 Kudos

When i am doing Ping and checking in SM04 it shows me only 1 user.

But when i am calling my Function Module using .Net Connector i can see 2 users immediately in SM04. Now from this 2 sessions in SM04 1 is active and another remains inactive all the time. After certain time of idle that 1 session goes out(terminated) automatically.

But i can't understand why it shows me 2 sessions when even i am calling only 1 function at that point of time.

If i forcefully terminate that inactive session from SAP GUI from SM04 , then also it does not cause any issue, because that is actually in non of use.

Please give me solution how can i avoid such circumstances.

hynek_petrak
Active Participant
0 Kudos

AFAIK .NET connector opens one or more connection(s) for “application level” function calls and a separate connection that lookup metadata repository information. By default same user is used, you may however configure a separate user for metadata lookup.

See the Programming Guide. https://websmp208.sap-ag.de/~sapidb/011000358700000769232010D/NCo_30_ProgrammingGuide.pdf

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi,

it's exactly as described by Hynek: When using dynamic repositories, NCo will lookup metadata through a separated connection pool. It is recommended to specify REPOSITORY_USER for this purpose (separation of concerns!), as thus it is possible to assign exactly the required permissions for  that purpose to this user and all application related users can be restricted to the application permissions. In case metadata is already cached, the connection will no longer be used and after some time the idle timeout checker will close the connection in the repository pool.

Best regards,

Markus

Former Member
0 Kudos

Thanks for this information.. I was really not knowing this thing.

Can you please provide me some link or demo source code which demonstrates this.

Otherwise can you provide me any particular property or method of SAP connector which help me to achieve this.

Former Member
0 Kudos

Sorry i found the answer of my question in your reply."REPOSITORY_USER " is the property which i have to use ..Thanks a lot.

Former Member
0 Kudos

I have a requirement where I need to make calls to SAP. For that I am registering --> getting the data from SAP --> and un-registering the the destination.

But Some times I am receiving the error message saying:

"cannot unregister the given destination configuration" . I know that since I am doing it frequently its occurring. Has anyone faced this earlier.

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Anand,

as already said in your own thread, this is the wrong approach, for what you desire to achieve.


Best regards,

Markus

Former Member
0 Kudos

To register a destination use: RfcDestinationManager.RegisterDestinationConfiguration(objConnectionConfig);

//where objConnectionConfig is the implementation of interface IDestinationConfiguration

I also faced this issue finally use Unregister destination like this.

RfcDestinationManager.UnregisterDestinationConfiguration(objConnectionConfig);

Hope this helps.

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Anurag,

You don't register a destination by this, but an IDestinationConfiguration, which is the full set of destinations, which is available to applications in that environment.

Best regards,

Markus

Former Member
0 Kudos

Try running the garbage collector on the object to release unused object.

GC.Collect();

GC.WaitForPendingFinalizers();

Former Member
0 Kudos

Solved by reading the tutorials and testing them with my requirements.

Former Member
0 Kudos

Hi,

Have the same issue but with a different variant. I'm using CreateCustomDestination to differentiate the end-user; the problem is that I would like to close the connection when it's not required anymore.

The parameter IDLE_TIMEOUT take the minimum of 15-20Minutes (parameter value = 1) until the connection is closed.

Any ideas on how we can have a better control on it?

Regards

Former Member
0 Kudos

I have used RemoveDestination call to logoff explicitly.

Set one property to true in your class after doing all the Rfc communications. explicitly. So whenever the value in the property is set to TRUE, call the Logoff.

In case my answer is not upto mark, then please paste the your sample code so that i can do some modification in it and help you.

Former Member
0 Kudos

Issue is resolved.

Following method mentioned in the Sap .Nco 3.0 tutorial, helped me in resolving the issue.

File: CustomDestinationConfiguration.cs

Class: InMemoryDestinationConfiguration

Method: RemoveDestination()


public class Form1(

private void btnLogon_Click(object sender, EventArgs e)
        {

            objDestConfig = new InMemoryDestinationConfiguration();

            //RfcDestinationManager destination = RfcDestinationManager.GetDestination("TEST1");

            RfcDestinationManager.RegisterDestinationConfiguration(objDestConfig);
            Console.WriteLine("Registered own configuration");
            objDestConfig.AddOrEditDestination("TESTW47", 1, "MyUsername", "MyPassword", "EN", "800", "192.168.101.15", "00");

            RfcDestination destination1 = RfcDestinationManager.GetDestination("TEST1");
            destination1.Ping();

            MessageBox.Show("Wait here");

            objDestConfig.RemoveDestination("TESTW47");
            //SimpleLogon();
        }
}

public class InMemoryDestinationConfiguration : IDestinationConfiguration
    {
        Dictionary<string, RfcConfigParameters> availableDestinations;
        RfcDestinationManager.ConfigurationChangeHandler changeHandler;

        public InMemoryDestinationConfiguration()
        {
            availableDestinations=new Dictionary<string, RfcConfigParameters>();
        }

        public RfcConfigParameters GetParameters(string destinationName)
        {
            RfcConfigParameters foundDestination;
            availableDestinations.TryGetValue(destinationName, out foundDestination);
            return foundDestination;
        }

        //our configuration supports events
        public bool ChangeEventsSupported()
        {
            return true;
        }

        public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged
        {
            add
            {
                changeHandler=value;
            }
            remove
            {
                //do nothing
            }
        }

        //removes the destination that is known under the given name
        public void RemoveDestination(string name)
        {
            if (name != null && availableDestinations.Remove(name))
            {
                Console.WriteLine("Successfully removed destination " + name);
                Console.WriteLine("Fire deletion event for destination " + name);
                changeHandler(name, new RfcConfigurationEventArgs(RfcConfigParameters.EventType.DELETED));
            }
        }

        //allows adding or modifying a destination for a specific application server
        public void AddOrEditDestination(string name, int poolSize, string user, string password, string language, string client, string applicationServer, string systemNumber)
        {
            //in productive code the given parameters should be checked for validity, e.g. that name is not null
            //as this is not relevant for the example, we omit it here
            RfcConfigParameters parameters = new RfcConfigParameters();
            parameters[RfcConfigParameters.Name] = name;
            parameters[RfcConfigParameters.MaxPoolSize] = Convert.ToString(poolSize);
            parameters[RfcConfigParameters.IdleTimeout] = Convert.ToString(1); // we keep connections for 10 minutes
            parameters[RfcConfigParameters.User] = user;
            parameters[RfcConfigParameters.Password] = password;
            parameters[RfcConfigParameters.Client] = client;
            parameters[RfcConfigParameters.Language] = language;
            parameters[RfcConfigParameters.AppServerHost] = applicationServer;
            parameters[RfcConfigParameters.SystemNumber] = systemNumber;
            RfcConfigParameters existingConfiguration;

            //if a destination of that name existed before, we need to fire a change event
            if (availableDestinations.TryGetValue(name, out existingConfiguration))
            {
                availableDestinations[name] = parameters;
                RfcConfigurationEventArgs eventArgs = new RfcConfigurationEventArgs(RfcConfigParameters.EventType.CHANGED, parameters);
                MessageBox.Show("Fire change event " + eventArgs.ToString() + " for destination " + name);
                changeHandler(name, eventArgs);
            }
            else
            {
                availableDestinations[name] = parameters;
            }

            MessageBox.Show("Added application server destination " + name);
            
        }

Edited by: HarminderSingh on Mar 29, 2011 12:36 PM

Former Member
0 Kudos

I'm having the same problem. It does that because the NCO 3.0 uses a connection pool. I just dont know how to clear the pool everytime so I can have different connections for every user.