我正在使用.Net Remoting(是的,我知道......那是旧的)来实现Windows服务中托管的一些服务类。
我在服务上调用方法DoOperation(Person[] people)
来更改Person
类中的某些属性,就像下面的代码一样:
Person p = new Person();
p.SomeProperty = "This value should be changed by the service";
RemoveSvc svc = (RemoveSvc)Activator.GetObject(
typeof(RemoveSvc),
"tcp://localhost:6100/RemoteService.rem");
svc.DoOperation(new Person[]{ p });
// This writes the old value not the one changed by the service.
Console.WriteLine(p.SomeProperty);
DoOperation
方法代码如下所示:
public void DoOperation(Person[] people) {
foreach(var o in people)
p.SomeProperty = "New Value";
}
这里的问题是,当方法返回时,Person.SomeProperty
的值未在客户端代码中更新。
我仔细检查过Person
类是否可序列化;
svc
变量的类型为TranparentProxy
;
RemoteSvc
类继承MarshalByRefObject
;
我正在使用.net Framework 4(不,我不能迁移到WCF)
我做错了什么? 这是.net Remoting的预期行为吗?如果是,有办法改变它吗?
韩国社交协会
答案 0 :(得分:2)
这不是服务的工作方式。服务不是内存操作。当您使用在本地计算机上编写的类执行所显示的操作时,您自然会看到对Person
对象的更改,因为您在调用方和方法之间传递了内存引用。当然,它是完全相同的人对象。
但是,当您使用服务或远程处理时,它不再是同一个人。事实上,你在问题中说明了这一点。您序列化此人,并通过电汇发送。它不是同一共享内存寄存器中的同一个人。因此,客户端中将看不到服务器上Person
的更改。
为了得到你想要的东西,这是你的功能签名。
public Person[] DoOperation(Person[] people);
您可以更改签名以保留参考。然后,对象将在客户端的服务器之间保持同步。 See this article了解更多信息。
public void DoOperation(ref Person[] people);
答案 1 :(得分:0)
Jarrett是对的,但这可能只是解决方案的一部分。问题是即使您传递对数组的引用,您仍然复制了数组中的Person
。因此,远程更改其中一个不会影响本地副本。您可能需要通过数组引用它们而不是使用本地引用。
我会尝试类似的事情:
var temp = new Person[]{ p }
svc.DoOperation(temp);
// This writes the old value not the one changed by the service.
Console.WriteLine(temp[0].SomeProperty);
可以使用远程调用创建的代理从远程位置获取Person
,而不是使用本地引用。