私はサービス ファブリックに不慣れで、このトピックを扱っている MSDN の記事を読むことから始めました。ここでHello World サンプルを実装することから始めました。
元の RunAsync 実装を次のように変更しました。
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<int, DataObject>>("myDictionary");
while (!cancellationToken.IsCancellationRequested)
{
DataObject dataObject;
using (var tx = this.StateManager.CreateTransaction())
{
var result = await myDictionary.TryGetValueAsync(tx, 1);
if (result.HasValue)
dataObject = result.Value;
else
dataObject = new DataObject();
//
dataObject.UpdateDate = DateTime.Now;
//
//ServiceEventSource.Current.ServiceMessage(
// this,
// "Current Counter Value: {0}",
// result.HasValue ? result.Value.ToString() : "Value does not exist.");
await myDictionary.AddOrUpdateAsync(tx, 1, dataObject, ((k, o) => dataObject));
await tx.CommitAsync();
}
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
また、DataObject 型を導入し、その型の UpdateDate プロパティを公開しました。
[DataContract(Namespace = "http://www.contoso.com")]
public class DataObject
{
[DataMember]
public DateTime UpdateDate { get; set; }
}
アプリを実行すると (Visual Studio 2015 では F5 キー)、dataObjectインスタンス (キーが 1) がディクショナリに見つからないため、作成して UpdateDate を設定し、ディクショナリに追加してトランザクションをコミットします。次のループでは、dataObject (キーが 1) を見つけて UpdateDate を設定し、ディクショナリ内のオブジェクトを更新して、トランザクションをコミットします。完全。
これが私の質問です。サービス プロジェクトを停止して再起動すると (Visual Studio 2015 では F5 キー)、RunAsync の最初の反復で、dataObject (キーが 1) が見つかると予想されますが、そうではありません。すべての状態がそのレプリカにフラッシュされることを期待します。
ステートフル サービスが内部状態をプライマリ レプリカにフラッシュするために何かする必要がありますか?
私が読んだところによると、これはすべてサービス ファブリックによって処理され、(トランザクションで) commit を呼び出すだけで十分であるかのように聞こえます。(Service Fabric Explorer->Application View で) プライマリ レプリカを見つけると、トランザクションをコミットすると (ステップ スルーするときに) RemoteReplicator_xxx LastACKProcessedTimeUTC が更新されていることがわかります。
どんな助けでも大歓迎です。
ありがとうございました!
-マーク