[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.remoting

Wiring up the remote events: the final bit of foolishness

Bob Rundle

7/14/2004 9:37:00 PM

Right...

Thanks to a lot of help from this group, I've almost got my .NET remoting
prototype put together..

There is one final bit of foolishness...wiring the remote events.

It almost works!

I have a OnChanged() event that the server will raise whenever a remote
object is changed.

Here is the way it is defined on the server
public delegate void OnChangedDelegate(joaItem item);

Here is the event...

public class joaCollection : joaItem, IEnumerable
{
public event OnChangedDelegate OnChanged;
//...
};

I tested the OnChanged event stand alone and it works great.

Now I defined an interface that is compiled into a shared class library to
be shared by client and server...

public interface joaCollectionEvents

{
void OnChanged(joaItem item);
// ...
}

Now on the client, I have a form that I want to add change handling event

public class joaPlatformForm : System.Windows.Forms.Form,
joaCollectionEvents
{
//...
private void LoadHandler(object sender, System.EventArgs e)
{
//...
platform.Workshops.OnChanged += new OnChangedDelegate(OnChanged);
}

void joaCollectionEvents.OnChanged(joaItem item)
{
UpdateData();
}

}

The problem: I can't get this to compile. The compiler complains that
OnChanged does not exist in joaPlatformForm. I've tried various syntax on
the line containing the "+=" without success.

What is the proper syntax?

Regards,
Bob Rundle






9 Answers

Ken Kolda

7/14/2004 10:11:00 PM

0

The correct syntax is:

platform.Workshops.OnChanged += new
OnChangedDelegate(((joaCollectionEvents)this).OnChanged);

That said, if you''re going to use events & delegates, you should know that
even though you''ve tried to hide your client implementation behind the
joaCollectionEvents interface, you''ll still have to have your client
assembly available on the server (and, in that case, there''s really no point
to using the joaCollectionEvents interface since you could pass a delegate
for any instance method).

If you want to achieve true separation of client and server, you''ll need to
implement your own callbacks and registration methods.

Ken


"Bob Rundle" <rundle@rundle.com> wrote in message
news:O8$jwqeaEHA.644@tk2msftngp13.phx.gbl...
> Right...
>
> Thanks to a lot of help from this group, I''ve almost got my .NET remoting
> prototype put together..
>
> There is one final bit of foolishness...wiring the remote events.
>
> It almost works!
>
> I have a OnChanged() event that the server will raise whenever a remote
> object is changed.
>
> Here is the way it is defined on the server
> public delegate void OnChangedDelegate(joaItem item);
>
> Here is the event...
>
> public class joaCollection : joaItem, IEnumerable
> {
> public event OnChangedDelegate OnChanged;
> //...
> };
>
> I tested the OnChanged event stand alone and it works great.
>
> Now I defined an interface that is compiled into a shared class library to
> be shared by client and server...
>
> public interface joaCollectionEvents
>
> {
> void OnChanged(joaItem item);
> // ...
> }
>
> Now on the client, I have a form that I want to add change handling event
>
> public class joaPlatformForm : System.Windows.Forms.Form,
> joaCollectionEvents
> {
> //...
> private void LoadHandler(object sender, System.EventArgs e)
> {
> //...
> platform.Workshops.OnChanged += new OnChangedDelegate(OnChanged);
> }
>
> void joaCollectionEvents.OnChanged(joaItem item)
> {
> UpdateData();
> }
>
> }
>
> The problem: I can''t get this to compile. The compiler complains that
> OnChanged does not exist in joaPlatformForm. I''ve tried various syntax on
> the line containing the "+=" without success.
>
> What is the proper syntax?
>
> Regards,
> Bob Rundle
>
>
>
>
>
>


Sunny

7/14/2004 10:19:00 PM

0

Hi,

attached is a sample event wrapper, which I use whenever I need events.

You have to consider 2 things, when using events:

1. If you have more than one client subscribed to an event, and one of
them fails or connection is lost, the other clients will not receive the
event as well. To go around it, read this (the second implementation is
what you need):
http://www.genuinechannels.com/Content.aspx?id=27&...


2. If your receiver is windows form, take in mind that all remoting
callbacks (incl. events) are executed on a different thread, and windows
forms are not thread safe. You have to use InvokeRequired and use Invoke
or BeginInvoke in your event handler, when you want to update the form.
Jon Skeet has very good article about threading, etc. (read at least the
part for winforms):

http://www.yoda.arachsys.com/csharp/multithre...

Cheers
Sunny



In article <O8$jwqeaEHA.644@tk2msftngp13.phx.gbl>, rundle@rundle.com
says...
> Right...
>
> Thanks to a lot of help from this group, I''ve almost got my .NET remoting
> prototype put together..
>
> There is one final bit of foolishness...wiring the remote events.
>
> It almost works!
>
> I have a OnChanged() event that the server will raise whenever a remote
> object is changed.
>
> Here is the way it is defined on the server
> public delegate void OnChangedDelegate(joaItem item);
>
> Here is the event...
>
> public class joaCollection : joaItem, IEnumerable
> {
> public event OnChangedDelegate OnChanged;
> //...
> };
>
> I tested the OnChanged event stand alone and it works great.
>
> Now I defined an interface that is compiled into a shared class library to
> be shared by client and server...
>
> public interface joaCollectionEvents
>
> {
> void OnChanged(joaItem item);
> // ...
> }
>
> Now on the client, I have a form that I want to add change handling event
>
> public class joaPlatformForm : System.Windows.Forms.Form,
> joaCollectionEvents
> {
> //...
> private void LoadHandler(object sender, System.EventArgs e)
> {
> //...
> platform.Workshops.OnChanged += new OnChangedDelegate(OnChanged);
> }
>
> void joaCollectionEvents.OnChanged(joaItem item)
> {
> UpdateData();
> }
>
> }
>
> The problem: I can''t get this to compile. The compiler complains that
> OnChanged does not exist in joaPlatformForm. I''ve tried various syntax on
> the line containing the "+=" without success.
>
> What is the proper syntax?
>
> Regards,
> Bob Rundle
>
>
>
>
>
>
>

Bob Rundle

7/14/2004 10:26:00 PM

0

Ken,

Indeed you are correct. I discovered that once I had the syntax correct, I
got a runtime serialization error indicating that server could not find the
client assembly.

My next step was to implement an abstract class in the shared assembly with
a derived class in the client. No good. The server still wants the client
assembly.

Finally I implemented a concrete class in the shared assembly and this
works!

But the whole point is to execute some client specific code. So now I need
to set a client reference in this shared concrete class...

Regards,
Bob Rundle

"Ken Kolda" <ken.kolda@elliemae-nospamplease.com> wrote in message
news:OA8cO%23eaEHA.644@tk2msftngp13.phx.gbl...
> The correct syntax is:
>
> platform.Workshops.OnChanged += new
> OnChangedDelegate(((joaCollectionEvents)this).OnChanged);
>
> That said, if you''re going to use events & delegates, you should know that
> even though you''ve tried to hide your client implementation behind the
> joaCollectionEvents interface, you''ll still have to have your client
> assembly available on the server (and, in that case, there''s really no
point
> to using the joaCollectionEvents interface since you could pass a delegate
> for any instance method).
>
> If you want to achieve true separation of client and server, you''ll need
to
> implement your own callbacks and registration methods.
>
> Ken
>
>
> "Bob Rundle" <rundle@rundle.com> wrote in message
> news:O8$jwqeaEHA.644@tk2msftngp13.phx.gbl...
> > Right...
> >
> > Thanks to a lot of help from this group, I''ve almost got my .NET
remoting
> > prototype put together..
> >
> > There is one final bit of foolishness...wiring the remote events.
> >
> > It almost works!
> >
> > I have a OnChanged() event that the server will raise whenever a remote
> > object is changed.
> >
> > Here is the way it is defined on the server
> > public delegate void OnChangedDelegate(joaItem item);
> >
> > Here is the event...
> >
> > public class joaCollection : joaItem, IEnumerable
> > {
> > public event OnChangedDelegate OnChanged;
> > //...
> > };
> >
> > I tested the OnChanged event stand alone and it works great.
> >
> > Now I defined an interface that is compiled into a shared class library
to
> > be shared by client and server...
> >
> > public interface joaCollectionEvents
> >
> > {
> > void OnChanged(joaItem item);
> > // ...
> > }
> >
> > Now on the client, I have a form that I want to add change handling
event
> >
> > public class joaPlatformForm : System.Windows.Forms.Form,
> > joaCollectionEvents
> > {
> > //...
> > private void LoadHandler(object sender, System.EventArgs e)
> > {
> > //...
> > platform.Workshops.OnChanged += new OnChangedDelegate(OnChanged);
> > }
> >
> > void joaCollectionEvents.OnChanged(joaItem item)
> > {
> > UpdateData();
> > }
> >
> > }
> >
> > The problem: I can''t get this to compile. The compiler complains that
> > OnChanged does not exist in joaPlatformForm. I''ve tried various syntax
on
> > the line containing the "+=" without success.
> >
> > What is the proper syntax?
> >
> > Regards,
> > Bob Rundle
> >
> >
> >
> >
> >
> >
>
>


Ken Kolda

7/14/2004 10:41:00 PM

0

See Sunny''s example of an event wrapper -- this is probably the easiest way
to deal with this issue without exposing your client to the server. That
said, as Sunny suggests, if you''re going to have multiple clients listening
for these events, I would avoid using server-based events. Using your own
callback is more work but provides greater control over what happens when an
error occurs invoking the event handler for a disconnected client.

Ken


"Bob Rundle" <rundle@rundle.com> wrote in message
news:%2345LVGfaEHA.3692@TK2MSFTNGP09.phx.gbl...
> Ken,
>
> Indeed you are correct. I discovered that once I had the syntax correct,
I
> got a runtime serialization error indicating that server could not find
the
> client assembly.
>
> My next step was to implement an abstract class in the shared assembly
with
> a derived class in the client. No good. The server still wants the client
> assembly.
>
> Finally I implemented a concrete class in the shared assembly and this
> works!
>
> But the whole point is to execute some client specific code. So now I
need
> to set a client reference in this shared concrete class...
>
> Regards,
> Bob Rundle
>
> "Ken Kolda" <ken.kolda@elliemae-nospamplease.com> wrote in message
> news:OA8cO%23eaEHA.644@tk2msftngp13.phx.gbl...
> > The correct syntax is:
> >
> > platform.Workshops.OnChanged += new
> > OnChangedDelegate(((joaCollectionEvents)this).OnChanged);
> >
> > That said, if you''re going to use events & delegates, you should know
that
> > even though you''ve tried to hide your client implementation behind the
> > joaCollectionEvents interface, you''ll still have to have your client
> > assembly available on the server (and, in that case, there''s really no
> point
> > to using the joaCollectionEvents interface since you could pass a
delegate
> > for any instance method).
> >
> > If you want to achieve true separation of client and server, you''ll need
> to
> > implement your own callbacks and registration methods.
> >
> > Ken
> >
> >
> > "Bob Rundle" <rundle@rundle.com> wrote in message
> > news:O8$jwqeaEHA.644@tk2msftngp13.phx.gbl...
> > > Right...
> > >
> > > Thanks to a lot of help from this group, I''ve almost got my .NET
> remoting
> > > prototype put together..
> > >
> > > There is one final bit of foolishness...wiring the remote events.
> > >
> > > It almost works!
> > >
> > > I have a OnChanged() event that the server will raise whenever a
remote
> > > object is changed.
> > >
> > > Here is the way it is defined on the server
> > > public delegate void OnChangedDelegate(joaItem item);
> > >
> > > Here is the event...
> > >
> > > public class joaCollection : joaItem, IEnumerable
> > > {
> > > public event OnChangedDelegate OnChanged;
> > > //...
> > > };
> > >
> > > I tested the OnChanged event stand alone and it works great.
> > >
> > > Now I defined an interface that is compiled into a shared class
library
> to
> > > be shared by client and server...
> > >
> > > public interface joaCollectionEvents
> > >
> > > {
> > > void OnChanged(joaItem item);
> > > // ...
> > > }
> > >
> > > Now on the client, I have a form that I want to add change handling
> event
> > >
> > > public class joaPlatformForm : System.Windows.Forms.Form,
> > > joaCollectionEvents
> > > {
> > > //...
> > > private void LoadHandler(object sender, System.EventArgs e)
> > > {
> > > //...
> > > platform.Workshops.OnChanged += new OnChangedDelegate(OnChanged);
> > > }
> > >
> > > void joaCollectionEvents.OnChanged(joaItem item)
> > > {
> > > UpdateData();
> > > }
> > >
> > > }
> > >
> > > The problem: I can''t get this to compile. The compiler complains
that
> > > OnChanged does not exist in joaPlatformForm. I''ve tried various
syntax
> on
> > > the line containing the "+=" without success.
> > >
> > > What is the proper syntax?
> > >
> > > Regards,
> > > Bob Rundle
> > >
> > >
> > >
> > >
> > >
> > >
> >
> >
>
>


Bob Rundle

7/15/2004 3:19:00 PM

0

Sunny,

Thanks very much for the code. It is an absolutely perfect example of
remoting events boiled down to the absolute essentials. You should give a
workshop to the MSDN people. All the examples in MSDN are either (1) far
too complex with all kinds of extraneous BS or (2) so trivial that you want
to go pound on them.

So I''ve got a lot further with my prototype as a result of your example.
The biggest problem was that my event hander was not derived from MBR
(Doh!!!). The events were actually being delivered in the server!

But its not completely working. I''ve got this error when the server tries
to raise the event...

Additional information: This remoting proxy has no channel sink which means
either the server has no registered server channels that are listening, or
this application has no suitable client channel to talk to the server.



I''ve tried to follow your example exactly with regard to channel setup on
client and server. I''m using a TCP channel version a HTTP channel, but I
can''t believe that this is the problem. I''ll keep working with the example.

Regards,
Bob Rundle



"Sunny" <sunny@newsgroups.nospam> wrote in message
news:OuFqWGfaEHA.2792@TK2MSFTNGP09.phx.gbl...
> ...
>
> and the code
>
>
> ....
>


Matthew Murfin

7/15/2004 5:11:00 PM

0

Sunny, Thanks for Pure-Simple-Works example!

I tried to add 2 items to demo multiple clients connecting and disconnecting but my clients will not un-hook the server event
multicast delegate.
1: Hack clients to each have a ''unique'' port: (hmmm... will need server to assign unique ports...)
--DUMMY unique port testing all on my local machine
props["port"] = System.AppDomain.GetCurrentThreadId();

2: Clients try to unhook on exit:
iServer.MyEvent -= new MyEventHandlerDelegate(eventWrapper.ServerEventHandler);

The code in item 2 does not seem to properly unhook on the server side. I get ''disconnected'' exceptions when the server fires the
MyEvent. Depending on which client I close (and where it''s delegate is in the multicast list) the rest of the clients stop
receiving server events.

What am I missing?

--
Thanks,
Matt MurfinSimmons
mmurfinsimmons@stigov_RMVTHIS_.com

"Sunny" <sunny@newsgroups.nospam> wrote in message news:OuFqWGfaEHA.2792@TK2MSFTNGP09.phx.gbl...
> ...
>
> and the code
>
>
> ....
>


Bob Rundle

7/15/2004 7:00:00 PM

0

Nevermind...it''s all working now. It turns out that, on the client side, I
had the channel creation and registration code nicely encapsulated in a
method. Only one problem...I never bothered to call the method! Ouch.

Bob Rundle


"Bob Rundle" <rundle@rundle.com> wrote in message
news:%23LgtV8naEHA.644@tk2msftngp13.phx.gbl...
> Sunny,
>
> Thanks very much for the code. It is an absolutely perfect example of
> remoting events boiled down to the absolute essentials. You should give a
> workshop to the MSDN people. All the examples in MSDN are either (1) far
> too complex with all kinds of extraneous BS or (2) so trivial that you
want
> to go pound on them.
>
> So I''ve got a lot further with my prototype as a result of your example.
> The biggest problem was that my event hander was not derived from MBR
> (Doh!!!). The events were actually being delivered in the server!
>
> But its not completely working. I''ve got this error when the server tries
> to raise the event...
>
> Additional information: This remoting proxy has no channel sink which
means
> either the server has no registered server channels that are listening, or
> this application has no suitable client channel to talk to the server.
>
>
>
> I''ve tried to follow your example exactly with regard to channel setup on
> client and server. I''m using a TCP channel version a HTTP channel, but I
> can''t believe that this is the problem. I''ll keep working with the
example.
>
> Regards,
> Bob Rundle
>
>
>
> "Sunny" <sunny@newsgroups.nospam> wrote in message
> news:OuFqWGfaEHA.2792@TK2MSFTNGP09.phx.gbl...
> > ...
> >
> > and the code
> >
> >
> > ....
> >
>
>


Sunny

7/15/2004 7:33:00 PM

0

Hi,

my foult. Thats what happens q/o good QA :)

Change the client code, in the part of the hooking like:

//do not hook directly, but hold a reference to the delegate
MyEventHandlerDelegate serverHanler = new MyEventHandlerDelegate
(eventWrapper.ServerEventHandler);

iServer.MyEvent += serverHanler;

and then unhooking is just:

iServer.MyEvent -= serverHanler;


So, this works, I have tried with 5 clients. The disconnection of any
one of them does not stop others.

But as I wrote in my prev. post, if the connection fails, and the client
does not unhook properly, this will stop other client from receiving the
event as well. I have provided a link to an article how to fire the
events safely at the server.

Sunny


In article <uMSeF7oaEHA.2056@TK2MSFTNGP12.phx.gbl>,
mmurfinsimmons@yaRMVTHIShoo.com says...
> Sunny, Thanks for Pure-Simple-Works example!
>
> I tried to add 2 items to demo multiple clients connecting and disconnecting but my clients will not un-hook the server event
> multicast delegate.
> 1: Hack clients to each have a ''unique'' port: (hmmm... will need server to assign unique ports...)
> --DUMMY unique port testing all on my local machine
> props["port"] = System.AppDomain.GetCurrentThreadId();
>
> 2: Clients try to unhook on exit:
> iServer.MyEvent -= new MyEventHandlerDelegate(eventWrapper.ServerEventHandler);
>
> The code in item 2 does not seem to properly unhook on the server side. I get ''disconnected'' exceptions when the server fires the
> MyEvent. Depending on which client I close (and where it''s delegate is in the multicast list) the rest of the clients stop
> receiving server events.
>
> What am I missing?
>
>

Matthew Murfin

7/15/2004 9:04:00 PM

0

That did it.
The other ''doh'' is that I was closing the console via the [X] close box and this was not hitting my finally{} section in any case!
--
Thank you,

Matt MurfinSimmons
mmurfinsimmons@stigov_RMVTHIS_.com

"Sunny" <sunny@newsgroups.nospam> wrote in message news:OGIWHKqaEHA.3204@TK2MSFTNGP09.phx.gbl...
> Hi,
>
> my foult. Thats what happens q/o good QA :)
>
> Change the client code, in the part of the hooking like:
>
> //do not hook directly, but hold a reference to the delegate
> MyEventHandlerDelegate serverHanler = new MyEventHandlerDelegate
> (eventWrapper.ServerEventHandler);
>
> iServer.MyEvent += serverHanler;
>
> and then unhooking is just:
>
> iServer.MyEvent -= serverHanler;
>
>
> So, this works, I have tried with 5 clients. The disconnection of any
> one of them does not stop others.
>
> But as I wrote in my prev. post, if the connection fails, and the client
> does not unhook properly, this will stop other client from receiving the
> event as well. I have provided a link to an article how to fire the
> events safely at the server.
>
> Sunny
>
>
> In article <uMSeF7oaEHA.2056@TK2MSFTNGP12.phx.gbl>,
> mmurfinsimmons@yaRMVTHIShoo.com says...
> > Sunny, Thanks for Pure-Simple-Works example!
> >
> > I tried to add 2 items to demo multiple clients connecting and disconnecting but my clients will not un-hook the server event
> > multicast delegate.
> > 1: Hack clients to each have a ''unique'' port: (hmmm... will need server to assign unique ports...)
> > --DUMMY unique port testing all on my local machine
> > props["port"] = System.AppDomain.GetCurrentThreadId();
> >
> > 2: Clients try to unhook on exit:
> > iServer.MyEvent -= new MyEventHandlerDelegate(eventWrapper.ServerEventHandler);
> >
> > The code in item 2 does not seem to properly unhook on the server side. I get ''disconnected'' exceptions when the server fires
the
> > MyEvent. Depending on which client I close (and where it''s delegate is in the multicast list) the rest of the clients stop
> > receiving server events.
> >
> > What am I missing?
> >
> >