したがって、私は wcf サービス、特に duplex について学び始めてまだ数日で、テスト アプリから始めています。目標は、変数を格納する内部 (静的?) クラスを持つ Service と、それらの変数をフェッチする Client を持つことです。
現在、Storage クラスには 2 つの変数があります。1 つは Subscribers のリスト ( ObservableCollection<IMyContractCallBack>
) で、もう 1 つは ですObservableCollection<string>
。各文字列はコールバック メソッドでクライアントに送信されます。
Fetch
サーバー側のコレクション内の文字列をクライアント (サーバー側のコレクションにコンテキストを追加することによって、まだサブスクライブしていない場合は最初にサブスクライブします) を取得できるようにしたいと考えています。その部分は期待どおりに機能します。Push
ただし、サーバーからサブスクリプション リスト内のすべてのクライアントに文字列を送信したり、Add
文字列のコレクションに文字列を送信したりしたいと考えています。それが私の問題が発生する場所です。
いつでもFetch
、文字列リスト「test1...」と「test2...」に追加して送信すると、クライアントはテキストブロックUI(wpa)を更新するため、2回フェッチすると、"test1...","test2...","test1...","test2..."
現在チェックがないため、取得できます重複用。Fetch
これは、コレクションが からまでサーバー側で更新および記憶できることを証明していますFetch
。ただし、特定のテキストを入力しようとするとAdd
、Send
すべての変数が忘れられてしまうため、購読者リストは null になり、追加先リストは空になります。それでも、Fetch
もう一度、古いリストが戻ってきました(現在は6つのものがありますtest1...,test2... etc...
)
授業前にこれを持っています
[ServiceBehavior(InstanceContextMode= InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
また、シングルトン コンテキスト モードを試してみましたが、役に立ちませんでした。を Multiple に変更しConcurrencyMode
ても、何も変わりません。内部コマンドがサーバー自体から送信された場合にのみ静的データがリセットされる理由についてのアイデアはありますか?
私のサービスのコードは次のとおりです。
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);
}
}
}
必要に応じて、さらにコードを提供できます。