所以我正在学习WCF,我遇到了一个我认为与Instance Control / State有关的问题,但我不确定。
工作流程如下,基本客户端/服务器范例。
客户端调用Method RetrieveBusinessObjects(条件),服务器调用数据层,然后将它们放在服务器端的IList中。它不会将此列表返回给调用客户端。
然后,客户端将调用一个方法,例如DisplayBusinessObjects(),它将从服务器检索IList,对它们进行序列化,将它们通过网络并显示它们。
如果我使用WCFTestClient尝试这个,它可以工作。如果我从一个实际的客户端运行它然后我得到一个大小为0的BusinessObject []。对我来说,这表示我没有要返回的对象。
这是状态管理问题还是我错过了什么?
答案 0 :(得分:3)
您需要考虑这一点:默认情况下,每次调用WCF服务都会导致新创建的服务类实例。
因此,如果您第一次调用RetrieveBusinessObjects(.....),则会实例化服务类的新实例,检索项并将其存储在对象实例中 - 当调用完成时,实例为被处置掉了。
您对DisplayBusinessObjects()的第二次调用将再次获得服务类的新实例 - 并且它不知道先前的调用,因此它的BusinessObject数组中没有任何内容 - 毕竟它是一个新的实例
这种情况不能很好地运行 - 您需要重新设计解决方案,以便单个调用将获取并返回业务对象列表 - 然后将它们缓存在客户端上。或者您需要在服务器上使用持久性缓存/存储来缓存在调用之间获取的那些项目。
答案 1 :(得分:0)
我同意@marc_s,因为您应该考虑使您的服务操作更粗糙,并考虑在单个操作中组合它们。您没有说明为什么您的第一个电话必须将数据存储在服务层中,而只是在第二个电话中将其返回。
但是,如果您在服务实现中绝对需要这种方法,那么您可以使用每个会话实例来实现该服务:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IService
{
private MyState _myState;
public MyService()
{
_myState = new MyState();
}
public void RetrieveBusinessObjects(...)
{
_myState.Items = GetDataFromDataLayer();
}
public IList<Item> DisplayBusinessObjects()
{
return _myState.Items;
}
}
这可以确保每个客户端获得自己的服务实例,并且它是内部状态。然而,这种方法不能很好地扩展,因此您可能需要在决定之前对其进行研究。