When remoting is used to call an overloaded generic method, a strange problem occurs. The following is an example.
1. No heavy load
Assume that the remoting interface is icomputer:
Public interface icomputer
{
Int add <tentity> (tentity C );
}
The implementation on the remoting server is very simple:
Public class computer: icomputer
{
Public int add <tentity> (tentity C)
{
Return 0;
}
}
Then, use spring.net to configure the remoting channel of the server and client respectively, and then the client makes the following calls:
Icomputer remotecomupter = (icomputer) program. springcontext. GetObject ("remotingcomputer ");
Int RES2 = remotecomupter. Add <gamerecorddetail> (New gamerecorddetail ());
This call is successful and there is no problem. The returned value is 0.
2. Add an overload
We add an overload method for the icomputer interface as follows:
Public interface icomputer
{
Int add <tentity> (tentity C );
IntAdd <tentity> (ilist <tentity>List );
}
The server directly returns 0 for the implementation of the overload method. When the client calls the preceding method again, system. nullreferenceexception is thrown. The stack location of the exception is:
Server stack trace:
In system. runtime. remoting. messaging. methodcall. resolvemethod (Boolean bthrowifnotresolved)
In system. runtime. remoting. messaging. methodcall.. ctor (Object handlerobject, binarymethodcallmessage smuggledmsg)
In system. runtime. serialization. formatters. Binary. binarymethodcall. readarray (object [] calla, object handlerobject)
In system. runtime. serialization. formatters. Binary. objectreader. deserialize (headerhandler handler, _ binaryparser serparser, Boolean fcheck, Boolean iscrossappdomain, imethodcallmessage methodcallmessage)
In system. runtime. serialization. formatters. Binary. binaryformatter. deserialize (Stream serializationstream, headerhandler handler, Boolean fcheck, Boolean iscrossappdomain, imethodcallmessage methodcallmessage)
In system. runtime. remoting. channels. corechannel. deserializebinaryrequestmessage (string objecturi, stream inputstream, Boolean bstrictbinding, typefilterlevel securitylevel)
In system. runtime. remoting. channels. binaryserverformattersink. processmessage (receivsinkstack, iMessage requestmsg, receivrequestheaders, stream requeststream, iMessage & responsemsg, response & responseheaders, stream & responsestream)
Exception rethrown at [0]:
In system. runtime. remoting. proxies. realproxy. handlereturnmessage (iMessage reqmsg, iMessage retmsg)
In system. runtime. remoting. proxies. realproxy. privateinvoke (messagedata & msgdata, int32 type)
In remotinglib. icomputer. Add [tentity] (tentity C)
3. Eliminate overloading by modifying the method name
Now, rename the method added later to Add2. The client calls the previous method again, and everything returns to normal.
4. the overload is still used, but the generic parameters are removed.
Now we can restore the overload, But remove the generic parameters, as shown below:
Public interface icomputer
{
Int add (gamerecorddetail C );
Int add (ilist <gamerecorddetail> list );
}
The server returns 0 directly for the implementation of the two methods. The client calls the previous method again, and everything is normal.
5. Test Results
Based on the above test, we can conclude that the conditions for the above strange phenomenon are as follows:
1. The target method called through remoting must be generic.
2. The target method called through remoting must be overloaded.
If the two conditions are met, the above system. nullreferenceexception will be thrown when the target method is called. So why? Exploring the answer ......
To solve this problem, we currently use the solution to remove the overload by renaming the method name.