Go Back   ZeroC Forums > Help Center

Reply
 
LinkBack Thread Tools Rate Thread Display Modes
  #1 (permalink)  
Old 12-06-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
Create C# threads as background threads?

Hello,

We are using Ice to implement a number of services which are used by a number of financial applications. The libraries that these applications use do not directly expose any Ice objects, so the applications are unaware that Ice is being used under the hood. In particular, they are not directly creating a Communicator, and are therefore not directly calling destroy() on it.

One problem that we have run into in c# is that because the threads created by Ice are created as foreground threads (the default), they will not permit the application to exit, even if the main thread exits. We therefore have had to jump through some hoops to make sure that each app explicitly does a bunch of cleanup work, which can be easily forgotten.

Would you see any problems with setting the threads that Ice creates to be background threads (Thread.IsBackground = true), to prevent them from keeping the app alive once the main thread terminates?

Thanks,
Brett
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #2 (permalink)  
Old 12-06-2006
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 912
Thanks for the suggestion. I will try this. I don't anticipate a problem, because user code is required to call Communicator::destroy() before it exits, at which point the Ice run time joins with all outstanding threads. But better be safe than sorry...

Cheers,

Michi.
Reply With Quote
  #3 (permalink)  
Old 12-07-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
Thanks for trying this out. As you mentioned, the app should call Communicator::destroy(), but failure to do so shouldn't cause the app to hang.

It's especially problematic in GUI apps, where the user closes the main window and thinks the app is dead, when in fact it is still running, but just isn't visible.

Thanks again,
Brett
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #4 (permalink)  
Old 12-07-2006
marc's Avatar
marc marc is offline
ZeroC Staff
 
Name: Marc Laukien
Organization: ZeroC, Inc.
Project: The Internet Communications Engine
 
Join Date: Feb 2003
Location: Florida
Posts: 1,781
Note that there might be other foreground threads from other libraries or from our own application that can prevent the application from terminating. If you really want to terminate a C# application non-gracefully, why not use Process.Kill()?
Reply With Quote
  #5 (permalink)  
Old 12-07-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
Hi Marc,

I'm not looking to kill the app non-gracefully. I'm just looking to have it exit normally, by returning from Main(). Ideally everything would be properly destroyed(), but I don't consider not doing it non-graceful. Maybe it's my Unix/C++ background, but I feel that when an app returns from main() it should be dead, whether or not all of the proper shutdown methods have been called.

Clearly other libraries could have created foreground threads as well. When I find them, I'll email their authors as well. :-)

Thanks,
Brett
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #6 (permalink)  
Old 12-07-2006
marc's Avatar
marc marc is offline
ZeroC Staff
 
Name: Marc Laukien
Organization: ZeroC, Inc.
Project: The Internet Communications Engine
 
Join Date: Feb 2003
Location: Florida
Posts: 1,781
As far as Ice is concerned, if you do not call destroy() on the communicator, the application does not shut down gracefully. This might or might not matter for your application, but to be on the safe side, I highly recommend to call destroy() on the communicator instead of just terminating the application.

If you use Ice for C++, you must call destroy() on the communicator, otherwise bad things will happen (such as crashes on shutdown). The behavior of C++ applications is completely undefined if you return from main() without first joining with all other threads. Calling destroy() on the communicator takes care of this.
Reply With Quote
  #7 (permalink)  
Old 12-08-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
I completely agree that all apps, whether C# or C++, should call destroy(), and that failure to do so is a bug. All I am saying is that the penalty for such a bug should be abrupt termination, possibly resulting in a crash. The current behavior in C# of keeping the process alive with no means of killing it besides finding it on the Processes tab of Task Manager (it won't even show up under Applications or the Taskbar), serves no benefit. At least with a crash, it is immediately obvious that something went wrong, and our users can immediately inform the developers. I just don't see any downside to setting the threads to be background threads. It will have no effect on well behaved apps, but it will prevent ill-behaved apps from consuming system resources.

On a related note, would it be possible to have Communicator implement IDisposable (where Dispose() calls destroy()), so that it can integrate more seamlessly with the standard cleanup mechanisms that C# and its libraries provide?

Thanks again,
Brett
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #8 (permalink)  
Old 12-11-2006
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 912
Quote:
Originally Posted by bpolivka View Post
On a related note, would it be possible to have Communicator implement IDisposable (where Dispose() calls destroy()), so that it can integrate more seamlessly with the standard cleanup mechanisms that C# and its libraries provide?
Hmmm... Doing this would be possible. I guess this would be one way to ensure that, if an application calls Exit(), Communicator.destroy() will actually be called. I'll have a look at this--I'm not sure I can see all the consequences just yet...

Cheers,

Michi.
Reply With Quote
  #9 (permalink)  
Old 12-11-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
It still wouldn't be automatically cleaned up at exit(), but it would allow Communicators to integrate with a lot of the component management frameworks (Windsor, Spring, System.ComponentModel, etc.) that are out there. They all allow an app to construct a container of components, and destroy them all at shutdown by Destroy()ing the container. If the components implement IDisposable, their respective Destroy() members will be called.

We are currently using a container like this, along with a wrapper around a Communicator, to allow libraries to register components that the app needs to dispose of at shutdown. If Communicator implemented IDisposable directly, we wouldn't need the wrapper.

Thanks,
Brett
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #10 (permalink)  
Old 12-11-2006
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 912
No, not good. Marc just pointed out that calling Exit() from within an operation implementation would cause deadlock if we do this.

Michi.
Reply With Quote
  #11 (permalink)  
Old 12-11-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
What isn't good? Creating threads as background threads, or implementing IDisposable?

I can't imagine why implementing IDisposable would cause deadlock. Calling Exit() will not automatically call Dispose(). The app still has to take explicit action to make that happen.
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #12 (permalink)  
Old 12-12-2006
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 912
Implementing IDisposable isn't good. The run time will finalize on exit and call Dispose() if the application hasn't done that yet. If Exit() is called from within an operation implementation in a server, that would cause deadlock, as far as I can see.

Cheers,

Michi.
Reply With Quote
  #13 (permalink)  
Old 12-12-2006
bpolivka bpolivka is offline
Registered User
 
Name: Brett Polivka
Organization: Magnetar Capital
Project: Financial Core Services
 
Join Date: Feb 2006
Posts: 15
Not to continue to drag this out, but the runtime may run finalizers at Exit(), but it will not automatically call Dispose(). Something has to take explicit action for Dispose() to be called. If you run the following example, you will see that the finalizer is called, but Dispose() never is:

using System;

namespace DisposeTest
{
class Junk : IDisposable
{
public Junk()
{
}

~Junk()
{
Console.WriteLine("Finalizer called");
}

public void Dispose()
{
Console.WriteLine("In Dispose()");
}
}

class Program
{
static void Main(string[] args)
{
Junk junk = new Junk();
Environment.Exit(1);
}
}
}


I don't mean to be annoying, and I really appriciate the time you guys have spent responding to this issue. If you don't want to implement either of the ideas discussed in this thread, I completely respect your decision. I just wanted to share some minor pain points I have encountered while using your excellent framework, and suggest some ideas.

Thank you for all of your time, and keep up the great work!!

Thanks,
Brett
__________________
Brett Polivka
Core Financial Systems
Magnetar Capital LLC
Reply With Quote
  #14 (permalink)  
Old 12-13-2006
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 912
Quote:
Originally Posted by bpolivka View Post
Not to continue to drag this out, but the runtime may run finalizers at Exit(), but it will not automatically call Dispose(). Something has to take explicit action for Dispose() to be called.
Oops, yes, you are right. It's not clear to me what adding a Dispose() method would achieve then though. In effect, it would just be an alias for Communicator.destroy(). Who would call the Dispose() method (if not the application)? Or, to put it differently, if the application doesn't call destroy(), would it be any more likely to call Dispose?

Quote:
I don't mean to be annoying, and I really appriciate the time you guys have spent responding to this issue. If you don't want to implement either of the ideas discussed in this thread, I completely respect your decision. I just wanted to share some minor pain points I have encountered while using your excellent framework, and suggest some ideas.
No, you are not annoying at all. Feedback like yours is important--without it, we'd be continuing to develop in ignorance! (See my editorial in Issue 18 of Connections.)

Cheers,

Michi.
Reply With Quote
  #15 (permalink)  
Old 12-13-2006
rdilipk rdilipk is offline
Registered User
 
Name: Dilip Ranganathan
Organization: 3M
Project: None
 
Join Date: Jul 2003
Location: Minnesota, USA
Posts: 35
"Oops, yes, you are right. It's not clear to me what adding a Dispose() method would achieve then though. In effect, it would just be an alias for Communicator.destroy(). Who would call the Dispose() method (if not the application)? Or, to put it differently, if the application doesn't call destroy(), would it be any more likely to call Dispose?"

Even the application forgets to call Dispose, the communicator's finalizer code will call Dispose() subject to some boolean checks.
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
Threads and Shutdown acbell Help Center 1 11-30-2006 06:16 AM
Java VM Crash within Ice.CommunicatorI.destroy and many threads w/ Prioxies. jae Help Center 3 10-17-2006 10:09 PM
Precisely how are Ice threads implemented? ChrisC Help Center 8 12-22-2005 12:39 PM
Multiple threads smashing the stack Ric Help Center 8 06-09-2005 01:55 PM
Contexts and threads aaron Help Center 2 01-27-2004 01:59 PM


All times are GMT -4. The time now is 12:58 PM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0
(c) 2008 ZeroC, Inc.