SapNwRfc
SapNwRfc copied to clipboard
Keep reference to generic server function delegates so they don't get GCed and crash the application
Extracted the fix from https://github.com/huysentruitw/SapNwRfc/pull/53
Fixes https://github.com/huysentruitw/SapNwRfc/issues/56
I'm looking forward to this making it into the library as I currently have it manually implemented in my code. I've run into one small thing while using it though and want to mention it. In my application, I need to be able to Stop/Start the RFC Server.
I can do a _server.Shutdown()
and _server.Launch()
, but if I fully dispose my ISapServer
and re-create it, I run into the GC issue after launching my new instance. Generally, I think this is OK and works for my current purposes. However, it seems like the only way to really destroy the server and delegates is to fully recycle the application.
@tom-j-irvine can you please show some code where you would run into the GC issue? Or are you referring to the implementation in #53 ?
Here is what works:
private ISapServer _sapServer;
// ... lots of other code
private void StartRfcServer()
{
// force shutdown if already running
StopRfcServer(false);
// start
_logger.LogInformation("Starting RFC server");
try
{
if (_sapServer == null)
{
_sapServer = SapServer.Create(_config.GetRfcServerParameters());
SapServer.InstallGenericServerFunctionHandler(
_config.GetRfcDestinationParameters(),
(connection, function) => HandleFunction(function)
);
}
_sapServer.Launch();
_logger.LogInformation("RFC server started");
}
catch (Exception ex)
{
_logger.LogError("Exception starting RFC server: {message}", ex.Message);
}
}
private void StopRfcServer(bool logShutdown = true)
{
if (_sapServer != null)
{
if (logShutdown) _logger.LogInformation("Stopping RFC server");
try
{
_sapServer.Shutdown(2000);
if (logShutdown) _logger.LogInformation("RFC server stopped");
}
catch (Exception ex)
{
_logger.LogWarning("Exception shutting down RFC server: {message}", ex.Message);
}
}
}
As I said, this works for my purposes. However, I had a version of the code where during shutdown, I would completely dispose the _sapServer
and assign null back to it. Then, after starting it back up with Create
and InstallGenericServerFunctionHandler
, I would run into the GC issue.
I'm really not sure this matters, but there does seem to be something lingering if you create a server and try to destroy it. I imagine things could get funky if you tried to create multiple servers too, but hopefully no one would try to do that.
Thanks! I will investigate it.
It looks like that calling RfcInstallGenericServerFunction
multiple times does not work. So I changed the code that calling SapServer.InstallGenericServerFunctionHandler
multiple times will only set the user delegates and RfcInstallGenericServerFunction
is just called the first time. Which avoids wrapping the users methods but introduces a few more static fields.