Hi Simon,

One way events don't throw exceptions when the listener is unreachable.
I don't use oneway events and remove listeners from my list when they
don't respond:

foreach (Delegate del in MessageArrived.GetInvocationList())
               {
                   try
                   {
                       handler = (MessageArrivedHandler) del;
                       handler(msg);
                   }
                   catch (Exception e)
                   {
                       // put logic here, if you want to give them
another chance, or a timout...
                       MessageArrived -= handler;
                   }
               }

There's extra overhead for non-oneway remoting of events, but if you
want to remove non-responding listeners this is an option.  I haven't
done any research on gc usage when there are non-responding listeners,
but the lag was around 5-10 seconds/non-responding listener/event call.

Brian


Hewitt, Simon C. (Contractor) wrote:

I have a client/server app as follows:
The server service has various 'monitors' that generate data
periodically. When data becomes available, it is placed onto a
MessageBus which passes the information to any subscribed listener (via
an IMessageListener interface).
I have a 'ClientConnection' class, which implements IMessageListener,
and passes messages from the server's message bus to a client's
'Connection' class, via an IRemoteMessageListener interface, which puts
these remote messages onto the client's local message bus. The same
happens in reverse and so the ClientConnection and Connection classes
act as a bridge passing messages between the two systems.
I have implemented the transmission to the other system as [OneWay]
since there is no return value.

When there are no clients connected, the service has around 3MB of GC
memory and this is fairly constant.
When a client connects to the service, everything works as expected and
server memory stays around the same.

However when the client disconnects (eventually I will add code so that
the client sends a disconnect message before closing down and have the
server detects clients no longer connected and dispose of the
connection), I would expect that the message sent would just disappear
since the server doesn't wait for a return value but what happens is
that memory starts to slowly increase until around 1GB when OutOfMemory
exceptions get thrown. Also the Handle count increases (a rough estimate
looking at log files indicates by 2 for every message sent to a
disconnected client) so instead of around 700-800 this increases to
50,000+ before memory is full.

Here are some declarations:-

       public class ClientConnection: MarshalByRefObject,
IDashboardConnection {...}

       public class Connection: MarshalByRefObject,
IDashboardConnection {...}

       public interface IDashboardConnection: IMessageListener,
IRemoteMessageListener {
         IIdentity Identity { get; }
         IIdentity RemoteIdentity { get; }
       }

       public interface IRemoteMessageListener {
         [OneWay]
         void RemoteReceive(IMessage message);
       }

       public interface IMessageListener {
         void MessageReceived(IMessage baseMessage);
       }


When the service has some data to send to a client, it arrives in this
method in ClientConnection:-
       void IMessageListener.MessageReceived(IMessage message) {
         ... <removed for clarity - just decides whether the message
should go to the remote client or not> ...
         remoteClient.RemoteReceive(message); // remoteClient is
defined as IRemoteMessageListener and is therefore [OneWay]
       // No exception is thrown by this line
         ... <removed for clarity - updates statistics etc. > ...
       }

As I understand it, a proxy created by the remoting infrastructure uses
a threadpool thread to communicate with the remote client, sees that the
method in OneWay and doesn't wait for a reply.
All this works fine when the client can be reached but if it can't then
my guess is that some exception is caught internally but the handler is
not cleaning up properly and holding onto references and/or handles.

Any idea if this is correct and if there is anything I can do about it.
(If it can't be fixed then I'll remove the OneWay attribute, catch
exceptions for non-listening clients and then dispose of the connection
if the client is still not contactable after a certain period or number
of attempts)

Cheers
Simon

===================================
This list is hosted by DevelopMentor�  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com




===================================
This list is hosted by DevelopMentor�  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to