Sqlite→Realm置き換えチャレンジ


昨日から Realm を触ってみてます。

てーれって、てれれれれ♪

拾い物画像

スペランカー(英:Spelunker)とは、
1. 「“無謀な”洞窟探検家」を意味する名詞。対義語は「ケイバー(英:caver)」。

            -- ニコニコ大百科(仮)

その1

var realm = Realms.Realm.GetInstance(dbPath);
var timer = new System.Threading.Timer(_ =>
{
  var rows = realm.All<Record>();

例外がスローされました: 'System.Exception' (Realm.dll の中)
 'System.Exception' の例外が Realm.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
Realm accessed from incorrect thread.

Realm オブジェクトを作成したスレッドと違うスレッドでクエリをかけると死ぬらしい。

var realm = Realms.Realm.GetInstance(dbPath);
var timer = new System.Threading.Timer(_ =>
{
  var rows = Realms.Realm.GetInstance(dbPath).All<Record>();

に修正。

その2

class DataModel {
  IQueryable<Record> GetRecords() { 
    using(var r = Realms.Realm.GetInstance(dbPath)) 
      return r.All<Record>(); 
  }
}

var timer = new System.Threading.Timer(_ =>
{
  foreach (var novel in /*■*/DataModel.GetRecords()/*■*/)

例外がスローされました: 'Realms.Exceptions.RealmException' (Realm.dll の中)
 'Realms.Exceptions.RealmException' の例外が Realm.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
Access to invalidated Results objects

うかつな using.
IQuery が帰るだけなので、まだクエリが終わっていない。
GetRecords での using をやめ。

その3

{
  foreach (var r in DataModel.GetRecords().Where(_ => )) 
  {
    await Task.Run(() => 
    {
      var id = r.ID;

例外がスローされました: 'System.Exception' (Realm.dll の中)
 'System.Exception' の例外が Realm.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
Realm accessed from incorrect thread.

クエリ結果のオブジェクトでも違うスレッドで触ると、怒られる。
id を Task の Action から外出し。

その4

{
  foreach (var r in DataModel.GetRecords().Where(_ => )) 
  {
    var id = r.ID;
    var result = await Task<int>.Run(() => 
    {
    }).ConfigureAwait(false);
    r.col = result;

例外がスローされました: 'Realms.Exceptions.RealmInvalidTransactionException' (Realm.dll の中)
 'Realms.Exceptions.RealmInvalidTransactionException' の例外が Realm.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
Cannot modify managed objects outside of a write transaction.

メンバーを触った瞬間、Update がかかるらしいよ。

r.Realm.Write(() => { r.col = result; });

その5

{
  foreach (var r in DataModel.GetRecords().Where(_ => )) 
  {
    var id = r.ID;
    var result = await Task<int>.Run(() => 
    {
    }).ConfigureAwait(false);
    r.Realm.Write(() => { r.col = result; });

例外がスローされました: 'System.Exception' (Realm.dll の中)
 'System.Exception' の例外が Realm.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
Realm accessed from incorrect thread.

Task を ConfigureAwait(false) しちゃったのが問題。

    }).ConfigureAwait(true);

でも問題は治らない。ConfigureAwait の呼び出し自体をやめると行けた。よくわかってない。

ぶっちゃけて

この10行ほどに今日一日かけてる・・・。
まだまだ伸びそう。