WinForms & Remoting

G

Guest

Hello,

Basically, I want my application to run only one instance at a time and pass
command line arguments to a running instance. I have all of this working, I
used the IPC Remoting channel and my program handles the command line
arguments well. However, after my program has been running for a little while
(say 5-10 minutes) the command line arguments no longer are passed, and
instead it causes a .NET Remoting exception claiming to have come across a
null reference.

So in my Program.cs file, I have something like this.

if (alreadyrunning)
{
IpcChannel ipcCh = new IpcChannel("MyProgram_" + username);
ChannelServices.RegisterChannel(ipcCh, false);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingService),
"Remoting", WellKnownObjectMode.Singleton);
ISharedAssemblyInterface obj = (ISharedAssemblyInterface)
Activator.GetObject(typeof(ISharedAssemblyInterface),
"ipc://MyProgram_" + username + "/Remoting");
obj.RunFirstInstance(arguments);
}
else
{
ISharedAssemblyInterface obj = (ISharedAssemblyInterface)
Activator.GetObject(typeof(ISharedAssemblyInterface),
"ipc://MyProgram_" + username + "/Remoting");
obj.HandleCommandLineArgs(arguments);
}


Again, it all works for a short time, but stops working claiming a null
reference on the HandleCommandLineArgs method after a while. I'm guessing
that even though I specifify a Singleton instance that it somehow gets
garbage collected or a new RemotingService class generated (even though my
program is still running).

Thanks in advance,
mitch

p.s. Sorry if this is a double post, I think my last one went into a thread,
instead of starting it's own topic.
 
G

Guest

As a side note, here is a simplified verson of my RemotingService.cs code:

namespace MyProject
{
public class RemotingService : MarshalByRefObject,
ISharedAssemblyInterface
{
MainForm mainform = null;
bool firstrun = true;
//--------------------------------------------------------------------------------------------
public RemotingService()
{
}
//--------------------------------------------------------------------------------------------
public void RunFirstInstance(string[] arguments)
{
mainform = new MainForm();
mainform.Show();
HandleCommandLineArgs(arguments);
Application.Run();
}
//--------------------------------------------------------------------------------------------
public void HandleCommandLineArgs(string[] arguments)
{
try
{
MethodInvoker myCallback = new MethodInvoker(
delegate()
{
Arguments args = new Arguments(arguments);
// do something with arguments
MainForm.Show();
});
MainForm.Invoke(myCallback);
}
catch (Exception e)
{
MessageBox.Show("ERROR " + e.ToString());
}
}
//--------------------------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------------------
public interface ISharedAssemblyInterface
{
void HandleCommandLineArgs(string[] arguments);
void RunFirstInstance(string[] arguments);
}
//--------------------------------------------------------------------------------------------
}
 
G

Guest

Nicholas,

Yes I am using .NET 2.0, I will look into that class, it seems a little
awkward to tap into the VisualBasic namespace when I'm coding in C#, doesn't
it? Is it possible there is a bug in remoting? I would jump on the
WindowsApplicationBase class, but my code *does* work for a while....until it
times out and stops working...

Thank you,
mitch
 
C

Colin Stutley

The GC has determined that ipcCh is no longer required and can be
collected - yeah a bit overzelous.

Change;
obj.RunFirstInstance(arguments);
to
obj.RunFirstInstance(arguments);
try { string keeprunning = ipcCh .ToString(); }
catch(Exception) { }

This will 'fool' the GC into keeping the remoting service active.
Keep this in mind for any planned long life objects.

- Colin
 
G

Guest

mitch said:
Hello,

Basically, I want my application to run only one instance at a time and pass
command line arguments to a running instance. I have all of this working, I
used the IPC Remoting channel and my program handles the command line
arguments well. However, after my program has been running for a little while
(say 5-10 minutes) the command line arguments no longer are passed, and
instead it causes a .NET Remoting exception claiming to have come across a
null reference.

So in my Program.cs file, I have something like this.

if (alreadyrunning)
{
IpcChannel ipcCh = new IpcChannel("MyProgram_" + username);
ChannelServices.RegisterChannel(ipcCh, false);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingService),
"Remoting", WellKnownObjectMode.Singleton);
ISharedAssemblyInterface obj = (ISharedAssemblyInterface)
Activator.GetObject(typeof(ISharedAssemblyInterface),
"ipc://MyProgram_" + username + "/Remoting");
obj.RunFirstInstance(arguments);
}
else
{
ISharedAssemblyInterface obj = (ISharedAssemblyInterface)
Activator.GetObject(typeof(ISharedAssemblyInterface),
"ipc://MyProgram_" + username + "/Remoting");
obj.HandleCommandLineArgs(arguments);
}


Again, it all works for a short time, but stops working claiming a null
reference on the HandleCommandLineArgs method after a while. I'm guessing
that even though I specifify a Singleton instance that it somehow gets
garbage collected or a new RemotingService class generated (even though my
program is still running).

Thanks in advance,
mitch

p.s. Sorry if this is a double post, I think my last one went into a thread,
instead of starting it's own topic.

I believe the problem is that you need to override the lifetime service of
your remoted Singleton, otherwise it gets collected by the garbage collector.
If you override InitializeLifetimeService in your remoted object, and return
null, this should ensure the object lives forever.

Remoting uses lease base lifetime services to control the lifetime of
remoted objects. As I have not used remoting for nearly a year, I cannot give
you a very good explanation, however if you Google Ingo Rammer you should
find some useful info.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top