首页 > 解决方案 > 如何在 .NET (Xamarin-UWP) 中创建的同一线程中访问 Realm 实例?

问题描述

我正在Xamarin Forms 中的应用程序中从 SQLite/ WebApis迁移到领域。

此应用程序管理消息传递服务(通过 SignalR 聊天)。

出现的问题是当收到一条消息时,我尝试将其存储在数据库中,应用程序意外崩溃。(SQLite 没有发生的问题)。

我收到了著名的错误:从不正确访问的领域,正是在尝试插入第三条或第四条消息时,很难看到确切的时刻。

正如我所读到的,无论是在 Stackoverflow 上的问题中,还是在 Dot-Net Realm GitHub 上的问题中。必须在创建它的同一线程中访问该实例。

正如他们所建议的那样,实现此目的的一种方法是通过 Stephen Cleary 的 Nito.AsyncEx 使用正确SynchronizationContext或.AsyncContext.Run Device.BeginInvokeOnMainThread

我问这个问题是因为不幸的是,我在基本级别上处理线程和任务的主题,我必须以什么方式处理以前对我的代码的建议?或者我应该正确设置什么来访问创建它的线程?

这是我的代码:

LobbyViewModel
public LobbyViewModel()
{
     ChatService.OnReceivePrivateMessage += ChatService_OnReceivePrivateMessage;
}

private async void ChatService_OnReceivePrivateMessage(object sender, MessageEventArgs args)
{
    await SendMessage(…);
}

private async Task SendMessage(…)
{
    await UpdateMetaData(…);
}

public async Task UpdateMetaData(…)
{
    await ManagerService.InsertMetaDataChatAsync(metaDataChat);
}

ManagerService
public async Task InsertMetaDataChatAsync (MetaDataChatModel MetaDataChatModel)
{

    IMetaDataChatServices MetaDataChatServices = App.AppContainer.Resolve<IMetaDataChatServices>();

    IResponse DataResult = (await MetaDataChatServices.Insert(MetaDataChatModel));

}

Repository
public async Task<IResponse> CreateAsync(MetaDataChatModel MetaDataChatModel)
        {
            MetaDataChatModel.Id = Guid.NewGuid().ToString();
            MetaDataChatModel.Partition = _realmManager.projectPartition;

            var MetaDataChatDto = MetaDataChatModel.ToDto();

            var realmInstance = await _realmManager.GetInstanceAsync();
            if (realmInstance == null)
                return new Response(false, "Realm instance can't be null");

            await realmInstance.WriteAsync(realm =>
            {
                realm.Add(MetaDataChatDto, false);
            });

            return new Response(true);
        }
        
RealmManager
public RealmManager()
{
    RealmApp = App.Create(appId);
    //DataBase = Realms.Realm.GetInstance(syncConfig);
}

public Task<Realms.Realm> GetInstanceAsync()
{
    return Realms.Realm.GetInstanceAsync(syncConfig);
}

public async Task RealmLogInAsync()
{
    if (RealmApp.CurrentUser == null)
    {
        User user = await RealmApp.
        LogInAsync(Credentials.EmailPassword("email", "password"));

        if (user == null)
        {
            return;
        }
    }

    projectPartition = $"project={RealmApp.CurrentUser.Id}";
    syncConfig = new SyncConfiguration(projectPartition, RealmApp.CurrentUser);
}

public async Task RealmLogOutAsync()
{
    if (RealmApp != null && RealmApp.CurrentUser!=null)
    {
        await RealmApp.CurrentUser?.LogOutAsync();
    }
}

标签: c#xamarinuwprealmsynchronizationcontext

解决方案


推荐阅读