多分私は何かを見逃しているかもしれませんが、同じオブジェクトであるレルムから並行して読み書きしているときに、奇妙な結果が得られます。
これは、より大きなプロジェクトで最初に発生しましたが、テスト プロジェクトで再現することができました。
シナリオ: 2 つのフィールドRealmObject
を持つ 1 つのオブジェクトDateTimeOffset
が作成され、毎分更新されます。別のスレッドが 10 秒ごとに読み取り、値を出力します。
最も関連性が高いため、最初に出力を表示します。括弧内の時刻は、出力がログに記録された時刻です。残りは識別子 (READER/WRITER) で、次にRealmObject
.
何が起こるかというと、書き込みが成功した後、リーダーはしばらく古い値を読み取り、次に新しい値を読み取り、古い値を再度読み取ります。アプリを再起動すると、もちろん、しばらくの間はすべて問題ありません。
//リーダーが読み取りを開始します。出力は正しい
[0:] (10:05:44.656) リーダー: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+ 00:00","IsManaged":true}] [0:] (10:05:54.656) リーダー: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate" :"2016-07-17T22:09:45.384+00:00","IsManaged":true}] [0:] (10:06:04.657) リーダー: [{"LastSyncTime":"2016-07-17T22: 04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+00:00","IsManaged":true}]
//Writer が入り、値を更新します。
[0:] (10:06:07.523) ライター: {"LastSyncTime":"2016-07-17T22:06:07.521+00:00","LastChangeDate":"2016-07-17T22:11:07.523+00 :00","IsManaged":true}
//Reader はしばらくの間、正しくない (OLD) 値を読み取ります
[0:] (10:06:14.661) リーダー: > [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384 +00:00","IsManaged":true}] [0:] (10:06:24.678) リーダー: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate ":"2016-07-17T22:09:45.384+00:00","IsManaged":true}] [0:] (10:06:34.678) リーダー: [{"LastSyncTime":"2016-07-17T22 :04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+00:00","IsManaged":true}]
//リーダーは突然正しい値を読み取ります
[0:] (10:06:44.678) リーダー: [{"LastSyncTime":"2016-07-17T22:06:07.521+00:00","LastChangeDate":"2016-07-17T22:11:07.523+ 00:00","IsManaged":true}]
//リーダーは以前の値に戻ります (????)
[0:] (10:06:54.678) リーダー: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+ 00:00","IsManaged":true}] [0:] (10:07:04.678) リーダー: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate" :"2016-07-17T22:09:45.384+00:00","IsManaged":true}]
コード:
public class TimestampDataObject : RealmObject
{
public DateTimeOffset LastSyncTime { get; set; }
public DateTimeOffset? LastChangeDate { get; set; }
}
書き込み部分:
Observable.Interval(TimeSpan.FromMinutes(1)).Subscribe(async (v) =>
{
await Realm.GetInstance().WriteAsync(r =>
{
var item = r.All<TimestampDataObject>().AsEnumerable().FirstOrDefault();
if (item == null)
{
item = r.CreateObject<TimestampDataObject>();
}
item.LastSyncTime = DateTimeOffset.UtcNow;
item.LastChangeDate = DateTimeOffset.UtcNow.AddMinutes(5);
Debug.WriteLine($"({DateTime.UtcNow.ToString("hh:mm:ss.fff")}) WRITER: {JsonConvert.SerializeObject(item)}");
});
});
読者:
Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(v =>
{
var latestTimestampInfo = Realm.GetInstance().All<TimestampDataObject>();
Debug.WriteLine($"({ DateTime.UtcNow.ToString("hh:mm:ss.fff")}) READER: {JsonConvert.SerializeObject(latestTimestampInfo)}");
});
何が起こるかわからない。おそらく、レルムの何人かがこれを明確にすることができます.
アップデート
さらにいくつかのテストを行ったところ、リーダーとライターが同じ場合、すべて正常に動作するようThread
です。タイムスタンプの直後にマネージド スレッド ID をログに追加しました。したがって、以下では、スレッド 11 で実行されているリーダー (ライターと同じ) が正常に動作する様子を確認できます。しかし、別のスレッドで実行されているリーダーは古い値を出力します。
//アップデート前(正解)
[0:] (10:56:53.679,11) リーダー: [{"LastSyncTime":"2016-07-17T22:55:55.573+00:00","LastChangeDate":"2016-07-17T23:00: 55.576+00:00","IsManaged":true}]
//更新はスレッド 11 で行われます
[0:] (10:56:55.552,11) ライター: {"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01:55.553 +00:00","IsManaged":true}
//スレッド 11 のリーダーは正しい値を出力します
[0:] (10:57:03.702,11) リーダー: [{"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01: 55.553+00:00","IsManaged":true}]
// 繰り返しますが、リーダーはスレッド 11 にあります。出力を修正してください。
[0:] (10:57:13.702,11) リーダー: [{"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01: 55.553+00:00","IsManaged":true}]
//スレッド 12 のリーダーが誤った結果を出力する
[0:] (10:57:23.703,12) リーダー: [{"LastSyncTime":"2016-07-17T22:23:19.674+00:00","LastChangeDate":"2016-07-17T22:28: 19.676+00:00","IsManaged":true}]
// 繰り返しますが、リーダーはスレッド 11 にあります。出力を修正してください。
[0:] (10:57:33.703,11) リーダー: [{"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01: 55.553+00:00","IsManaged":true}]