使ってみよう! Live Framework

第5回 .NET Kit(2)

この記事を読むのに必要な時間:およそ 5 分

衝突の検知

それでは,アプリケーションから衝突しているかどうかを知る方法とその解決方法を確認してみましょう。

Data Entryを列挙する際に これまで使用していたDataEntriesプロパティではなくSyncEntriesプロパティを使用します。SyncEntries.Entriesで列挙されるアイテムはDataEntries.Entriesと同じくDataEntry型です。また,すべてのDataEntriesの内容を含んでいます。ただし,既に削除されたData Entryも参照でき,同期や衝突に関する情報をDataEntry.Syncプロパティから取得することができます。以下に衝突しているData Entryを表示するコードを示します。単純に衝突しているかどうかを知るにはResource.Sync.Conflicts.Countプロパティが0か否かを確認します。

' Live Mesh フォルダの取得
Dim mos = From mo In loe.Mesh.MeshObjects.Entries _
   Where mo.Resource.Type = "LiveMeshFolder" _
   Take 1

' Data Feed 取得
Dim dataFeed = mos.SingleOrDefault.DataFeeds.Entries.First

' これまでの方法で Data Entry を参照する場合
'For Each de In dataFeed.DataEntries.Entries
'    Console.WriteLine(de.Resource.Title)
'Next

' Sync Entry
For Each se In dataFeed.SyncEntries.Entries
    If se.Resource.Sync.Conflicts.Count > 0 Then
        ' 衝突している Data Entry がある
        Console.WriteLine(se.Resource.Title)
    End If
Next

アプリケーションからData Entryを区別するにはResource.Idプロパティを使用するとよいでしょう。DataEntriesとSyncEntriesからどちらからも参照できるData Entryは同じResource.Idの値になっています。

既に削除されいてるData Entryは,Resource.IsDeletedプロパティにより参照できます。値がTrueの場合,既に削除されたData Entryです。

衝突の解決

続いて衝突したData Entryを解決,つまりどのバージョンのData Entryを残すかを決定します。最も簡単な方法は,衝突しているSyncEntryのResolveAllConflictsメソッドを呼び出し,SyncEntriesのSynchronizeメソッドを呼ぶことです。するとDataEntriesから参照できているData Entryのバージョンが選択されたことになり,衝突が解決されます。次にそのコードを示します。

' Sync Entry
For Each se In dataFeed.SyncEntries.Entries
    If se.Resource.Sync.Conflicts.Count > 0 Then
        ' 衝突している Data Entry がある

        se.ResolveAllConflicts()
    End If
Next
dataFeed.SyncEntries.Synchronize()

このコードを実行後に対象SyncEntryのResource.Sync.Conflicts.Countの値を確認すると0になっているはずです。

より詳しくData Entryの内容を確認してどのData Entryのバージョンを選択するかは,Data EntryのResource.Sync.Conflictsコレクションの内容を確認します。衝突の有無の確認に使用したコレクションですね。このコレクションにはDataEntriesから参照されていないData Entry情報が格納されています。以下にそのコードを示します。

For Each se In dataFeed.SyncEntries.Entries
    If se.Resource.Sync.Conflicts.Count > 0 Then

        ' 衝突している Data Entry の別バージョンの参照
        For Each s As DataEntryResource In de.Resource.Sync.Conflicts
            ' 比較に利用できる値の例
            Dim title = s.Title
            Dim publishDate = s.PublishDate
            Dim fistAuthor = s.Authors.First.Name
        Next
    End If
Next

Data Entryを含む全リソースには基本的な情報としてタイトルや更新日時,更新者などのプロパティが用意されているのでその値を参照しData Entryを選択します。

Resource.Sync.ConflictsコレクションにあるData Entryを残すデータとして選択する場合,SyncEntryのSetConflictingItemAsWinnerメソッドを呼び出し,その引数に対象のコレクションアイテムを指定します。以下のコードは単純に最初のコレクションアイテムを選択した場合のものです。

' Sync Entry
For Each se In dataFeed.SyncEntries.Entries
    If se.Resource.Sync.Conflicts.Count > 0 Then
        ' 衝突している Data Entry がある

        ' Data Entryの選択
        se.SetConflictingItemAsWinner(de.Resource.Sync.Conflicts.First)
    End If
Next
dataFeed.SyncEntries.Synchronize()

おわりに

今回はここまでです。簡単ではありますが,Mesh Objectの更新通知の受信と衝突およびその解決について主に紹介しました。このデータの同期に関する部分は,Live Frameworkの特徴というよりもFeedSyncをLive Frameworkが実施している形になっています。FeedSyncは,マイクロソフトが発表したWebベースの同期に関する仕様で,その内容は公開されており誰でも自由に利用することが可能です。

さて,次回はさらにLive Frameworkの内容についての紹介をするとともに,簡単なアプリケーションも作成していく予定です。

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp