C#异步调用和领域实例

问题描述 投票:0回答:1

我正在使用Realm和Xamarin Forms项目,我已经阅读过如何跨线程共享域实体实例。

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

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

enter image description here

xamarin xamarin.forms realm realm-mobile-platform
1个回答
3
投票

正在使用在100号线获得的路线,然后在等待104的呼叫后再次在109号线上访问,危险吗?

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

关键是使用SynchronizationContext,所以你的等待延续是在同一个线程上(当然,因为你将在不同的线程中,跳过使用基于Realm的异步方法)

Using Stephen Cleary's Nito.AsyncEx (he is the king of sync contexts 😜)

re:how can i force await to continue on the same thread?

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);
    }
});

Using SushiHangover.RealmThread

我为Realm编写了一个简单的SynchronizationContext,它可以满足我的需求,并且有一个专门用于Realm的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的事实......我在绝大多数项目中使用它。

© www.soinside.com 2019 - 2024. All rights reserved.