The concept does not say, please refer to MSDN related chapter:
Http://msdn.microsoft.com/library/chs/cpguide/html/cpconevents.asp Let's first transform the last program, add events for the last main thread method, can constantly trigger the event to report processing schedule:
public
Class
MyEventargs {
Private
int
_rate;
public
int
Rate {
get
{
Return
_rate;}}
public
MyEventargs
int
Rate) {
THIS
._Rate
=
Rate;}}
public
Class
MyObject {
public
Delegate
Void
MyEventHandler
Object
Sender, MyEventArgs E);
public
Event
Myeventhandler myevent;
public
Void
AlongTimeMethod
int
Time) {console.writeLine
"
Main thread method start
"
);
for
(
int
i
=
0
i
<
100
i
) {System.threading.thread.sleep (time); OnMyevent
New
Myeventargs (i));} console.writeline
"
Main thread method ends
"
}
protected
Void
ONMYEVENT (MyEventargs E) {
IF
(MyEvent)
! =
NULL
) {Myevent
THIS
, e);}}}}}
Then add a handler for an event:
Class
MyClient {[stathread]
Static
Void
Main
String
[] Args) {datetime dt
=
Datetime.now; myObject obj
=
New
MyObject (); obj.myevent
=
New
MyObject.myeventhandler (obj_myelent); obj.alongtimeMethod
50
Console.writeline
"
used
"
(Timespan) (DateTime.now)
-
DT)). Totalseconds
"
second
"
Console.readline ();
public
Static
Void
OBJ_MYEVENT
Object
Sender, myeventargs e) {console.writeLine
"
The main thread method is completed
"
E.rate
"
%
"
}}
Operating programs can be seen: Is this local, remote object event is also simple? In fact, there is no simplicity of imagination, because the object is in the distance, how can the server event client capture? It should be said that the event of the remote object can be divided into a client trigger - "Server Answer, Service Trigger -" Client Answers and Client Triggered - "Client Answer, the first is very simple, and two of the two need to have a middle Part. Below we have to add a progress mechanism to the schedule, first create our remote object: [SerializAble]
public
Class
Myeventargs: Eventargs {
Private
int
_rate;
Private
String
_ip;
public
int
Rate {
get
{
Return
_rate;}}
public
String
IP {
get
{
Return
_ip;}}
public
MyEventargs
int
Rate,
String
IP) {
THIS
._Rate
=
Rate;
THIS
._ip
=
IP;}}
public
Class
MyObject: MarshalByrefObject {
public
Delegate
Void
MyEventHandler
Object
Sender, MyEventArgs E);
public
Event
Myeventhandler myevent;
public
int
AlongTimeMethod
int
a,
int
b,
int
Time,
String
IP) {console.writeLine
"
Asynchronous method start
"
);
for
(
int
i
=
0
i
<
10
i
) {System.threading.thread.sleep (time); OnMyevent
New
MyEventArgs (i, IP));} console.writeline
"
End of asynchronous methods
"
);
Return
a
B;
protected
Void
ONMYEVENT (MyEventargs E) {
IF
(MyEvent)
! =
NULL
) {Myevent
THIS
, e);}}}}}
For the convenience of debugging, the server side and the client are implemented this time, the following is the server side:
Using
System;
Using
System.collections;
Using
System.Runtime.Remoting;
Using
System.Runtime.Remoting.Channels;
Using
System.Runtime.Remoting.Channels.tcp;
Using
System.Runtime.Serialization.formatters;
Namespace
RemoteServer {
Class
Myserver {[stathread]
Staticvoid
Main
String
[] Args) {remoteConfiguration.registerwellknownServiceType
Typeof
(RemoteObject.myObject),
"
RemoteObject.myObject
"
WellknownObjectMode.singleton; binaryserverformattersinkProvider ServerProvider
=
New
BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider
=
New
BinaryClientFormattersinkProvider (); ServerProvider.TypefilterLevel
=
TypefilterLevel.Full; IDictionary Props
=
New
Hashtable (); prOPS [
"
port
"
]
=
9999
TCPCHANNEL CHANNEL
=
New
TcpChannel (Props, ClientProvider, ServerProvider); ChannelServices.registerChannel (CHANNEL); Console.Readline ();}}}
For the sake of simplicity, I will go to the previous test of the local event:
Using
System;
Using
System.net;
Using
System.collections;
Using
System.Text;
Using
System.Runtime.Remoting;
Using
System.Runtime.Remoting.Channels;
Using
System.Runtime.Remoting.Channels.tcp;
Using
System.Runtime.Serialization.formatters;
Class
Myclient {
Private
Delegate
int
MyDelegate
int
a,
int
b,
int
Time,
String
IP);
Private
Static
MyDelegate md; [stathread]
Static
Void
Main
String
[] Args) {datetime dt
=
DateTime.now; RemotingConfiguration.registerwellknownClientType
Typeof
(RemoteObject.myObject),
"
TCP: // localhost: 9999 / RemoteObject.myObject
"
Binary ServerFormattersinkProvider ServerProvider
=
New
BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider
=
New
BinaryClientFormattersinkProvider (); serverProvider.TypefilterLevel =
TypefilterLevel.Full; IDictionary Props
=
New
Hashtable (); prOPS [
"
port
"
]
=
0
TCPCHANNEL CHANNEL
=
New
TcpChannel (Props, ClientProvider, ServerProvider); ChannelServices.registerChannel (Channel); RemoteObject.myObject APP
=
New
RemoteObject.myObject (); app.myevent
=
New
RemoteObject.myObject.myeventhandler (myEvent); MD
=
New
MyDelegate (app.alongtimeMethod); asyncCallback AC
=
New
AsyncCallback (MyClient.callback); iphostentry iphe
=
DNS.GETOSTBYNAME (DNS.GETHOSTNAME ()); IASYNCRESULT IAR
=
Md.BeginInvoke
1
,
2
,
300
, iphe.addresslist [
0
] .ToString (), AC,
NULL
); Method (); console.writeline
"
used
"
(Timespan) (DateTime.now)
-
DT)). Totalseconds
"
second
"
ChannelServices.unregisterChannel (CHANNEL); console.readline ();
public
Static
Void
Callback (IASYNCRESULT IAR) {
IF
(Iar.iscompleted) {console.writeLine
"
turn out
"
Md.Endinvoke (IAR);}}
public
Static
Void
Myevent
Object
Sender, RemoteObject.myeventargs e) {Console.WriteLine
"
From
"
E.IP
"
The asynchronous method is completed.
"
E.rate
*
10
"
%
"
}
public
Static
Void
Method () {console.writeline
"
Main thread method start
"
); System.threading.thread.sleep
5000
Console.writeline
"
Main thread method ends
"
}}
The code looks good, but Debug is started after the error: this is the problem I mentioned earlier, and the remote cannot have a local assembly, and the local event cannot be triggered. The solution is to add an event middleware to inherit MarshalByrefObject: Public
Class
EventClass: MarshalByrefObject {
public
Void
Myevent
Object
Sender, myeventargs e) {console.writeLine
"
From
"
E.IP
"
The asynchronous method is completed.
"
E.rate
*
10
"
%
"
}}
Then come to modify the client: put app.myevent = new remoteObject.myObject.myeventhandler (MyEvent);
RemoteObject.EventClass EC
=
New
RemoteObject.eventclass (); app.myevent
=
New
RemoteObject.myObject.myeventhandler (ec.myevent);
Delete the client's MyEvent static method. Run the program: The two windows before and after doing have the server and the client, which seems to have reached our request, in fact, the program has 2 vulnerabilities: 1. Open the new program after the client is closed, because the previous commission Chain loss, server program attempts to trigger event errors. 2, at the same time open several clients, the client receives all scheduled information, not just your own, broadcast nature news. (1) Close a client will affect other client events Reason: The client does not cancel the event subscription, it is closed, and the event subscriber can not find the event subscriber when the event is triggered: traverse the commission chain, find an exception, from the entrustment Removing (2) The server side is broadcast on the server side. The client can receive the event processing information for other clients: use the Singleton mode, share the remote object resolution: Because the remote object is status and does not share the instance, Client activation can select the modified server:
Using
System;
Using
System.collections;
Using
System.Runtime.Remoting;
Using
System.Runtime.Remoting.Channels;
Using
System.Runtime.Remoting.Channels.tcp;
Using
System.Runtime.Serialization.formatters;
Namespace
RemoteServer {
Class
Myserver {[stathread]
Static
Void
Main
String
[] Args) {remoteConfiguration.ApplicationName
=
"
RemoteObject.myObject
"
RemotingConfiguration.RegisterActiVatedServiceType
Typeof
(RemoteObject.myObject); binaryserverformattersinkProvider ServerProvider =
New
BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider
=
New
BinaryClientFormattersinkProvider (); ServerProvider.TypefilterLevel
=
TypefilterLevel.Full; IDictionary Props
=
New
Hashtable (); prOPS [
"
port
"
]
=
8888
TCPCHANNEL CHANNEL
=
New
TcpChannel (Props, ClientProvider, ServerProvider); ChannelServices.registerChannel (CHANNEL); Console.Readline ();}}}
Modified remote object:
Using
System;
Namespace
RemoteObject {[serializable]
public
Class
Myeventargs: Eventargs {
Private
int
_rate;
Private
String
_ip;
public
int
Rate {
get
{
Return
_rate;}}
public
String
IP {
get
{
Return
_ip;}}
public
MyEventargs
int
Rate,
String
IP) {
THIS
._Rate
=
Rate;
THIS
._ip
=
IP;}}
public
Class
MyObject: MarshalByrefObject {
public
Delegate
Void
MyEventHandler
Object
Sender, MyEventArgs E);
public
Event
Myeventhandler myevent;
public
String
TMP;
public
int
AlongTimeMethod
int
a,
int
b,
int
Time,
String
IP) {console.writeLine
"
From
"
IP
"
Asynchronous method begins
"
);
for
(
int
i
=
1
i
<=
10
i
) {System.threading.thread.sleep (time); console.writeline
"
From
"
IP
"
The asynchronous method is completed.
"
i
*
10
"
%
"
OnmyEvent
New
MyEventArgs (i, IP));} console.writeline
"
From
"
IP
"
End of asynchronous methods
"
);
Return
a
B;
protected
Void
ONMYEVENT (MyEventargs E) {
IF
(MyEvent)
! =
NULL
) {
Foreach
(Delegate D
in
MyEvent.getinvocationList ()) {
Try
{((MyEventHandler) D)
THIS
, e);
Catch
{MyEvent
- =
MyeventHandler D;}}}}}}
public
Class
EventClass: MarshalByrefObject {
public
Void
Myevent
Object
Sender, myeventargs e) {
IF
((MyObject) Sender) .tmp
==
E.IP) Console.WriteLine
"
The asynchronous method is completed.
"
E.rate
*
10
"
%
"
}}}
Modified client:
Using
System;
Using
System.net;
Using
System.collections;
Using
System.Text;
Using
System.Runtime.Remoting;
Using
System.Runtime.Remoting.Channels;
Using
System.Runtime.Remoting.Channels.tcp;
Using
System.Runtime.Serialization.formatters;
Class
Myclient {
Private
Delegate
int
MyDelegate
int
a,
int
b,
int
Time,
String
IP);
Private
Static
MyDelegate MD;
Static
RemoteObject.myObject app;
Static
RemoteObject.EventClass EC;
Static
DateTime dt; [stathread]
Static
Void
Main
String
[] Args) {dt
=
DateTime.now; RemotingConfiguration.registerActiVatedClientType
Typeof
(RemoteObject.myObject),
"
TCP: // localhost: 8888 / RemoteObject.myObject
"
Binary ServerFormattersinkProvider ServerProvider
=
New
BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider =
New
BinaryClientFormattersinkProvider (); ServerProvider.TypefilterLevel
=
TypefilterLevel.Full; IDictionary Props
=
New
Hashtable (); prOPS [
"
port
"
]
=
0
TCPCHANNEL CHANNEL
=
New
TCPChannel (Props, ClientProvider, ServerProvider); ChannelServices.RegisterChannel (CHANNEL); APP
=
New
RemoteObject.myObject (); EC
=
New
RemoteObject.eventclass (); app.myevent
=
New
RemoteObject.myObject.myeventhandler (ec.myevent); MD
=
New
MyDelegate (app.alongtimeMethod); asyncCallback AC
=
New
AsyncCallback (MyClient.callback); iphostentry iphe
=
DNS.GETHOSTBYNAME (DNS.GETHOSTNAME ()); Random Rnd
=
New
Random (system.environment.tickcount);
String
IP
=
Iphe.addresslist [
0
] .ToString ()
"
(
"
RND.NEXT
100000000
) .Tostring ()
"
)
"
App.TMP
=
IP; IASYNCRESULT IAR
=
Md.BeginInvoke
1
,
2
,
500
, IP, AC,
NULL
); Method (); console.writeline
"
used
"
(Timespan) (DateTime.now)
-
DT)). Totalseconds
"
second
"
ChannelServices.unregisterChannel (CHANNEL); console.readline ();
public
Static
Void
Callback (IASYNCRESULT IAR) {
IF
(Iar.iscompleted) {console.writeLine
"
turn out
"
Md.Endinvoke (IAR); app.myevent
- =
New
RemoteObject.myObject.myeventhandler (ec.myevent);}}
public
Static
Void
Method () {console.writeline
"Main thread method start
"
); System.threading.thread.sleep
5000
Console.writeline
"
Main thread method ends
"
}}
It is necessary to keep up with the random number behind the IP address because you may open multiple clients on a machine, you need to distinguish multiple clients at this time. Note: All of my examples are deployed remote objects on the client and server side. In fact, this practice is not very good, we should only deploy the interface in both places, and the remote object is only deployed on the server.