我正在尝试学习和使用WCF,但我对是否可以通过引用传递参数感到困惑。我挣扎了一段时间试图从我的客户端调用一个通过引用传递参数的操作合同(每次都会超时,即使本地机器上的服务和客户端也是如此)。但是,Visual Studio提供的测试客户端可以毫无问题地调用操作合同(即使使用引用参数)。我的客户端在调用仅包含值参数的操作合同时会成功。
我在MSDN上看过这篇文章,但我不能正确理解它,因为它似乎与自己相矛盾(至少我是如何解释的):http://msdn.microsoft.com/en-us/library/ms733070(v=vs.100).aspx
标题 "参数和返回值" 表示:
每个操作都有一个返回值和一个参数,即使它们是 无效。但是,与本地方法不同,您可以在其中传递引用 从一个对象到另一个对象的对象,服务操作不通过 对象的引用。相反,他们传递对象的副本。
在 " Out和Ref Parameters" 标题下进一步说明:
在大多数情况下,您可以使用参数(Visual Basic中的ByVal)和 out和ref参数(Visual Basic中的ByRef)。因为两者都出来了 ref参数表示从操作返回数据,a 操作签名如下指定a 即使操作,也需要请求/回复操作 签名返回无效。
我正在使用.net客户端的netTcpBinding和(至少在此时)尝试通过引用传递一个字符串。我错过了什么?这可能吗?
更新 看来如果我的操作契约没有返回一个类型(c#/ vb中的void / sub),那么我可以通过引用成功传递参数(甚至是多个参数)。我猜测它是如何设计的,因为参考参数取代了请求/回复操作中的返回值。
答案 0 :(得分:2)
是。你是对的。参考参数按值传递,如文档所述。他们制作副本。你是对的,使用的模型是Request \ Reply。原因是该引用真的是一天结束时的地址正确吗?因此,一台机器上的地址不会在另一台机器上得到相同的结果(请参阅我的观点?)。 数据发送和接收的方式是不同的。我想鼓励您查看添加服务引用时创建的代理类。此文件的名称通常是Reference.cs,您可以双击您的引用并通过对象浏览器访问它。
假设你的契约方法是int GetMyData(ref string modifyMe);
如果查看ServiceClient类(假设您的服务名为Service),您将看到GetMyDataRequest对象有一个string类型的成员,并且返回的GetMyDataResponse对象有两个类型为integer和string的成员。这就是ServiceClient类
中的包装器方法中发生的情况C#:
public int GetMyData(ref string value) {
WCFServiceClientApp.ServiceReference1.GetMyDataRequest inValue = new WCFServiceClientApp.ServiceReference1.GetMyDataRequest();
inValue.value = value;
WCFServiceClientApp.ServiceReference1.GetMyDataResponse retVal = ((WCFServiceClientApp.ServiceReference1.IService1)(this)).GetMyData(inValue);
value = retVal.value;
return retVal.GetMyDataResult;
}
VB:
Public Function GetMyData(ByRef value As String) As Integer
Dim inValue As ServiceReference1.GetMyDataRequest = New ServiceReference1.GetMyDataRequest()
inValue.value = value
Dim retVal As ServiceReference1.GetMyDataResponse = CType(Me,ServiceReference1.IService1).GetMyData(inValue)
value = retVal.value
Return retVal.GetMyDataResult
End Function
因此,对于您作为客户端,您的字符串将通过引用传递,但在引擎盖下,修改后的值将被分配回您传入的字符串变量。 希望这会有所帮助。
答案 1 :(得分:0)
可以通过ref参数使用但请记住
此外,使用out或ref参数要求操作具有底层证券 响应消息以带回修改后的对象。如果您的操作是单向的 操作,在运行时抛出InvalidOperationException异常。
答案 2 :(得分:0)
没有创建副本是不可能的。
如果您希望客户端直接操作服务器中的对象,反之亦然,请使用.NET Remoting这通常无论是否有效:
请参阅MarshalByRefObject 。与WCF不同,Remoting在幕后创建隐藏所有消息的代理。
.NET Remoting仍然很有用,因为必须使用它来与不同AppDomains中的对象进行通信。