【发布时间】:2012-07-20 17:38:13
【问题描述】:
所以我只有几天时间才能了解 wcf 服务,特别是双工服务,并且我开始使用测试应用程序。目标是拥有一个服务,该服务具有一个存储变量的内部(静态?)类,以及一个获取这些变量的客户端。
目前我在 Storage 类中有两个变量,一个是订阅者列表 (ObservableCollection<IMyContractCallBack>),另一个是 ObservableCollection<string>,其中每个字符串在回调方法中发送到客户端。
我希望能够让客户端Fetch(如果尚未订阅,则首先订阅,通过将其上下文添加到服务器端的集合)服务器端集合中的字符串。该部分按预期工作。但是,我还想将Push 一个字符串从服务器发送到订阅列表中的每个客户端,以及将Add 字符串发送到字符串集合。这就是我的问题出现的地方。
任何时候我Fetch,它都会添加到字符串列表“test1...”和“test2...”并发送它们,然后客户端更新一个文本块 UI (wpa),所以如果我获取两次,我将拥有"test1...","test2...","test1...","test2..." 因为现在没有检查重复项。这证明集合可以在服务器端从Fetch 更新和记忆到Fetch。但是,当我尝试Add 或Send 给定文本时,所有变量都被遗忘了,因此订阅者列表为空,而要添加的列表为空。然而,当我再次Fetch 时,旧列表又回来了(现在有 6 个东西,test1...,test2... etc...)
我上课前有这个
[ServiceBehavior(InstanceContextMode= InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
我还尝试了单例上下文模式,但无济于事。将 ConcurrencyMode 更改为 Multiple 也没有任何不同。关于为什么我的 static 数据仅在内部命令来自服务器本身时才被重置的任何想法?
这是我的服务的代码:
namespace WcfService3
{
[ServiceBehavior(InstanceContextMode= InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class Service1 : IService1
{
public static event Action NullContext;
public static ObservableCollection<IMyContractCallBack> Subscriptions;
public void NormalFunction()
{
//Only sends to Subs that are STILL Open
foreach (IMyContractCallBack user in Subscriptions)
{
//Removes the Closed users, because they are hanging around from last session
if (((ICommunicationObject)user).State != CommunicationState.Opened)
{
Subscriptions.Remove(user);
}
else
{
ObservableCollection<string> holder = Storage.GetList();
foreach (string str in holder)
{
user.CallBackFunction(str);
}
}
}
}
public static void Send(string str)
{
try
{
foreach (IMyContractCallBack user in Subscriptions)
{
user.CallBackFunction(str);
}
}
catch
{
//For some reason 'Subscriptions' is always null
NullContext.Invoke();
}
}
public static void Add(string str)
{
//For some reason 'SendList' is always null here, too
Storage.AddToList(str);
if (Subscriptions != null)
{
//For same reason 'Subscriptions' is always null
foreach (IMyContractCallBack user in Subscriptions)
{
user.CallBackFunction(str);
}
}
}
public void Subscribe()
{
//Adds the callback client to a list of Subscribers
IMyContractCallBack callback = OperationContext.Current.GetCallbackChannel<IMyContractCallBack>();
if (Subscriptions == null)
{
Subscriptions = new ObservableCollection<IMyContractCallBack>();
}
if(!Subscriptions.Contains(callback))
{
Subscriptions.Add(callback);
}
}
这是我的 Storage 类代码:
namespace WcfService3
{
public static class Storage
{
public static readonly ObservableCollection<string> SendList = new ObservableCollection<string>();
public static IMyContractCallBack callback;
public static ObservableCollection<string> GetList()
{
if (SendList.Count == 0)
{
AddToList("Test1...");
AddToList("Test2...");
}
return SendList;
}
public static void AddToList(string str)
{
SendList.Add(str);
}
}
}
如果需要,我可以提供更多代码。
【问题讨论】:
-
看起来问题出在您的代码中,因此您必须发布代码才能让他人帮助您。
-
好的,我添加了 svc.cs 文件的代码
-
该代码与您在问题中的描述不一致。
Storage是什么?Fetch()在哪里? -
Storage是一个静态类,现在在上面添加,Fetch()是来自客户端的调用,触发回调函数
NormalFunction