I have a .NET remoting client activated object type client-server application. I’m using Visual Studio 2010 targeting the .NET Framework 4. When I run without debugging, the program works fine – the clients can connect no problem. But when I try to debug, on the line in the client code where I have the ‘new’ operator, the server (I think) throws an exception.
What I want to do is keep references to the remote objects created in the server code. So in my Remote Object’s constructor I have this line:
Cache.GetInstance().addFireFighter(this);
When I debug, this code runs fine too. But when it goes back to the remote object’s line to call the addFireFighter method, that’s when it crashes. Here’s the addFireFighter method:
public static IServer _server;
public void addFireFighter(FireFighter ff)
{
_server.addFireFighter(ff);
}
And the _server.addFireFighter method:
public void addFireFighter(FireFighterResponder.FireFighter ff)
{
_ffList.Add(ff); // -> works fine :S
Console.WriteLine("FireFighterResponder addFireFighter added");
lstBox.Items.Add(ff); //-> CRASH!!
}
Observation: When I run the server without debugging but run the client in debug mode, it still works fine.
This is a school project and I’m new to C# .NET remoting. I implemented the same in Java and had no issue. So I can give my whole project if somebody wants to look at it. Maybe I have a design flaw.
Here’s the stack trace:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Cross-thread operation not valid: Control 'lstBox' accessed from a thread other than the thread it was created on. at System.Windows.Forms.Control.get_Handle() at System.Windows.Forms.ListBox.NativeAdd(Object item) at System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object item) at System.Windows.Forms.ListBox.ObjectCollection.Add(Object item) at FirefighterMonitorSystem.BaseStation.addFireFighter(FireFighter ff) in C:\Users\Dula\Documents\My Dropbox\Firefighter\453\FirefighterMonitorSystem\FirefighterMonitorSystem\BaseStation.cs:line 35 at FireFighterResponder.Cache.addFireFighter(FireFighter ff) in C:\Users\Dula\Documents\My Dropbox\Firefighter\453\FirefighterMonitorSystem\FireFighterResponder\Cache.cs:line 33 at FireFighterResponder.FireFighter..ctor() in C:\Users\Dula\Documents\My Dropbox\Firefighter\453\FirefighterMonitorSystem\FireFighterResponder\FireFighter.cs:line 20 --- End of inner exception stack trace ---
The lstBox is a .NET ListBox in my server code where I add each Remote object. But what still confuses me is why it works when not in debug mode.
You have to look at the exception’s InnerException property to know what went really wrong.
You are accessing a control from a thread other than the main thread (aka UI thread). This is illegal, windows are not thread-safe. You must use Control.Begin/Invoke(). You don’t get the exception without the debugger because this thread checking is only enabled by default when a debugger is attached. That doesn’t mean it is safe to run code without a debugger, it will randomly cause paint problems or deadlock, although you may have to wait a day or a week for that to happen.