C# 异步调用和领域实例

C# async calls and realm instances

我正在将 Realm 与 Xamarin Forms 项目一起使用,并且我已阅读有关如何无法跨线程共享领域实体实例的内容。

给定下面的代码,是使用第100行获取的route,然后在第104行awaited调用后,在第109行再次访问,危险吗?

我是 Realm 的新手,但如果这是真的,那么在 any/every awaited 调用之后必须获得一个新的 Realm 实例和正在使用的任何对象。好像很繁重...

is using the route obtained in line 100, and then accessed again on line 109 after the awaited call on 104, dangerous?

是的,在下一次 foreach 迭代中,您最终会得到一个不同的托管线程,而 Realm 将抛出一个不同的线程访问异常。

关键是使用 SynchronizationContext 这样你的 await continuations 在同一个线程上(当然,因为你将在不同的线程中,跳过使用基于领域的异步方法)

使用 Stephen Cleary 的 Nito.AsyncEx(他是同步上下文之王)

回复:

var yourRealmInstanceThread = new AsyncContextThread();
await yourRealmInstanceThread.Factory.Run(async () =>
{
    var asyncExBasedRealm = Realm.GetInstance();
    var routes = asyncExBasedRealm.All<UserModel>();
    foreach (var route in routes)
    {
        // map it
        // post it
        await Task.Delay(TimeSpan.FromMilliseconds(1)); // Simulate some Task, i.e. a httpclient request.... 
        // The following continuations will be executed on the proper thread
        asyncExBasedRealm.Write(() => route.Uploaded = true);
    }
});

使用SushiHangover.RealmThread

不久前我为 Realm 写了一个 simple SynchronizationContext,它可以满足我的需要并且有一个专门的 API领域.

using (var realmThread = new RealmThread(realm.Config))
{
    await realmThread.InvokeAsync(async myRealm =>
    {
        var routes = myRealm.All<UserModel>();
        foreach (var route in routes)
        {
            // map it
            // post it
            await Task.Delay(TimeSpan.FromMilliseconds(1)); 
            // The following continuations will be executed on the proper thread
            myRealm.Write(() => route.Uploaded = true);
        }
    });
}

注意: 对于不太理解 SynchronizationContext 的人,我强烈建议使用 Nito.AsyncEx 作为通用解决方案,该解决方案得到了很好的支持和应有的事实上,它来自 Stephen Cleary...我在我的绝大多数项目中都使用它。