Maybe I'm missing something out but I'm getting some weird results while reading and writing in parallel from Realm, same object.
I first encountered this in a bigger project but just managed now to reproduce it in a test project.
Scenario: one RealmObject
object with two DateTimeOffset
fields is created and then updated every minute. Another thread reads every 10 seconds and outputs the values.
I'll first show the output since it's most relevant. The time in the paranthesis is the time at which the output is logged. The rest is the identifier (READER/WRITER) and then the JSON representation of the RealmObject
.
What happens is that after a successful write, the reader reads the old values for a while, then reads the new value and then reads the old values again. If I restart the app then everything is OK, of course, for a while.
//Reader starts reading. The output is correct
[0:] (10:05:44.656) READER: [{"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) READER: [{"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) READER: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+00:00","IsManaged":true}]
//Writer comes in and updates the values.
[0:] (10:06:07.523) WRITER: {"LastSyncTime":"2016-07-17T22:06:07.521+00:00","LastChangeDate":"2016-07-17T22:11:07.523+00:00","IsManaged":true}
//Reader reads incorrect (OLD) values for a while
[0:] (10:06:14.661) READER: > [{"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) READER: [{"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) READER: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+00:00","IsManaged":true}]
//Reader suddnely reads correct values
[0:] (10:06:44.678) READER: [{"LastSyncTime":"2016-07-17T22:06:07.521+00:00","LastChangeDate":"2016-07-17T22:11:07.523+00:00","IsManaged":true}]
//Reader falls back to previous values (????)
[0:] (10:06:54.678) READER: [{"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) READER: [{"LastSyncTime":"2016-07-17T22:04:45.384+00:00","LastChangeDate":"2016-07-17T22:09:45.384+00:00","IsManaged":true}]
The code:
public class TimestampDataObject : RealmObject
{
public DateTimeOffset LastSyncTime { get; set; }
public DateTimeOffset? LastChangeDate { get; set; }
}
The writing part:
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)}");
});
});
The reader:
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)}");
});
Not sure what happens. Perhaps some of the Realm guys can clarify this.
UPDATE
Did some more tests and apparently it all works fine when the reader and writer are on the same Thread
. Added in the logs the managed thread id right after the timestamps. So, below you can see how a reader running on thread 11 - the same as the writer's - works fine. But a reader running on a different thread outputs the old values:
//Before the update (correct)
[0:] (10:56:53.679,11) READER: [{"LastSyncTime":"2016-07-17T22:55:55.573+00:00","LastChangeDate":"2016-07-17T23:00:55.576+00:00","IsManaged":true}]
//The update is done on thread 11
[0:] (10:56:55.552,11) WRITER: {"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01:55.553+00:00","IsManaged":true}
//Reader on thread 11 outputs correct values
[0:] (10:57:03.702,11) READER: [{"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01:55.553+00:00","IsManaged":true}]
//Again, the reader is on thread 11. Correct output.
[0:] (10:57:13.702,11) READER: [{"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01:55.553+00:00","IsManaged":true}]
//A reader on thread 12 outputs incorrect results
[0:] (10:57:23.703,12) READER: [{"LastSyncTime":"2016-07-17T22:23:19.674+00:00","LastChangeDate":"2016-07-17T22:28:19.676+00:00","IsManaged":true}]
//Again, the reader is on thread 11. Correct output.
[0:] (10:57:33.703,11) READER: [{"LastSyncTime":"2016-07-17T22:56:55.552+00:00","LastChangeDate":"2016-07-17T23:01:55.553+00:00","IsManaged":true}]