问题描述
我正在使用 RemotingServices.Marshal
和 Activator.GetObject
在驻留在同一台计算机上的两个简单程序之间建立远程处理通道.
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
我已经确认通道存在并且可以进行通信,因为两个程序都成功地将 number
和 text
更改为完全唯一的值(已确认).
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).
所以我立即尝试对 strings
做同样的事情.
So I immediately tried doing the same for strings
.
在一个程序中,我调用了strings.Add("1")
.我尝试在第二个程序中读取 strings
的内容.它是空.更重要的是,计数为0
.我不知道为什么 strings
仍然有 0
对象,就好像我从未添加过它们一样.对于 Stack
和 Dictionary
也会发生同样的事情,我只是无法向其中添加任何元素.为了确保引用类型一般不会发生什么奇怪的事情,我还尝试在 IPC 接口类中放置一个 StringBuilder
,并且在两个程序中成功地维护了状态",改变了它的价值.
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.
问题:为什么没有添加字符串列表,解决方法是什么?
我希望有经验的人可以立即发现这个问题.我尝试谷歌搜索类似的问题,但没有得到任何有用的结果.令人惊讶的是,我只得到了 1 个很好的链接来搜索调试 .net 远程透明代理".这也是我的第二个问题.如何调试透明代理对象?
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?
- 所有对象都被正确实例化(没有 NullReferenceException;事实上,没有异常).
推荐答案
问题在于 List
本身并不是 MarshalByRefObject
,而是一个可序列化的类.当您调用列表上的 Add()
方法时,您实际上是在要求远程对象序列化其列表,在本地反序列化,然后在本地对象上调用该方法.您的更改永远不会传播回列表对象的远程实例.
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.
您必须在 IpcInterface
类中提供方法来操作列表;因为这个类型继承自 MarshalByRefObject
,这些方法将在远程对象上调用,而不是在本地反序列化的实例上调用.
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.
即
public class IpcInterface : MarshalByRefObject {
public List<String> strings;
public void Add(string value) {
strings.Add(value);
}
}
您可能还想将 strings
作为只读集合公开,否则您会给人一种可以直接操作它的印象(它不能).
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).
这篇关于.NET Remoting,为什么列表不是远程的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!