问题
I'm using RemotingServices.Marshal
and Activator.GetObject
to establish a remoting channel between two simple programs residing on the same computer.
public class IpcInterface : MarshalByRefObject
{
public int number = -1;
public string text = "default";
public List<String> strings;
}
// A simplification
I've confirmed that the channel exists and communication is possible, because both programs are successfully changing number
and text
to completely unique values (confirmed).
So I immediately tried doing the same for strings
.
On one program, I called strings.Add("1")
. I tried reading the contents of strings
on the second program. It was empty. What's more, the count was 0
. I have no idea why strings
continues to have 0
objects, as if I never added them. The same thing happens for a Stack<T>
and Dictionary<T, K>
, I just can't add any elements to it. Just to be sure there wasn't something weird going on with reference types in general, I also tried putting a StringBuilder
in the IPC interface class, and that 'state' was successfully maintained across both programs changing its value.
Question: Why isn't the list of strings being added to, and what's the solution?
I'm hoping someone with experience can spot this problem right away. I tried Googling for similar questions, but I didn't get any useful results. Surprisingly, I only got 1 good link for googling "debugging .net remoting transparent proxy". That's a second question I have, too. How can I debug the transparent proxy object?
- All objects are instantiated properly (there is no NullReferenceException; in fact, there are no exceptions).
回答1:
The problem is that List<T>
is not in itself a MarshalByRefObject
, rather, it is a serializable class. When you call the Add()
method on your list, what you're actually doing is asking the remote object to serialise its list, deserialise it locally and then call the method on the local object. Your changes will never be propagated back to the remote instance of the list object.
You will have to provide methods in your IpcInterface
class to manipulate the list; because this type inherits from MarshalByRefObject
, the methods will be called on the remote object instead of a locally-deserialised instance.
i.e.
public class IpcInterface : MarshalByRefObject {
public List<String> strings;
public void Add(string value) {
strings.Add(value);
}
}
You may also want to expose strings
as a read-only collection, otherwise you're giving the impression that it can be manipulated directly (which it cannot).
来源:https://stackoverflow.com/questions/13486467/net-remoting-why-isnt-a-list-remotable