Xamarin Forms - 在错误的线程中访问 Realm

3
也许我错过了某些简单的东西,但是还是要问一下... 我在使用Xamarin表单(.NET标准项目)、MVVMLight、Realm DB和ZXing条形码扫描器。我有一个像这样的realmobject...
public class Participant : RealmObject
{
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public string Email {get; set;}
    public string RegistrationCode {get; set;}

    //More properties skipped out for brevity
}

我有一个对应的视图模型,如下所示:

public class ParticipantViewModel
{
    Realm RealmInstance
    public ParticipantViewModel()
    {
        RealmInstance = Realms.Realm.GetInstance();
        RefreshParticipants();
    }

    private async Task RefreshParticipants() 
    {
        //I have code here that GETS the list of Participants from an API and saves to the device.
        //I am using the above-defined RealmInstance to save to IQueryable<Participant> Participants
    }
}

所有上述内容都正常运行,我没有任何问题。在同一视图模型中,我还可以启动ZXing扫描器并扫描代表注册码的条形码。这将反过来填充下面的属性(也在视图模型中)一旦被扫描...
    private ZXing.Result result;
    public ZXing.Result Result
    {
        get { return result; }
        set { Set(() => Result, ref result, value); }
    }

并通过以下方法调用(通过ScanResultCommand进行连接)来获取扫描RegistrationCode的参与者。

    private async Task ScanResults()
    {
        if (Result != null && !String.IsNullOrWhiteSpace(Result.Text))
        {
            string regCode = Result.Text;
            await CloseScanner();
            SelectedParticipant = Participants.FirstOrDefault(p => p.RegistrationCode.Equals(regCode, StringComparison.OrdinalIgnoreCase));
            if (SelectedParticipant != null)
            {
                //Show details for the scanned Participant with regCode
            }
            else
            {
                //Display not found message
            }
        }
    }

我一直收到以下错误信息...
System.Exception: 从错误的线程访问Realm。
由下面的代码行生成...
SelectedParticipant = Participants.FirstOrDefault(p => p.RegistrationCode.Equals(regCode, StringComparison.OrdinalIgnoreCase));
我不确定这是如何成为错误的线程,但任何有关如何解决从已填充的IQueryable或直接从Realm表示中提取扫描参与者的想法都将不胜感激。
谢谢
1个回答

4

是的,在构造函数中您获取了一个 Realm 实例,然后在异步任务(或线程)中使用它。您只能从获取该引用的线程访问 Realm。由于您仅使用默认实例,因此应该能够在使用它的函数(或线程)中简单地获取本地引用。尝试使用。

    Realm LocalInstance = Realms.Realm.GetInstance();

在函数顶部创建RealmInstance的实例并使用它。你还需要重新创建Participants查询,以使用与其来源相同的实例。这将是使用异步任务(线程)时的情况,因此要么在进入时更改为获取默认实例,要么减少访问realm的线程数。

顺便说一下,在RefreshParticipants()中也不会出现类似的访问错误,访问数据时可能没有通过RealmInstance进行访问。


感谢您的回复。获取一个单独的本地实例并没有起作用,因为我有其他使用IQueryable<Participant>的代码片段,而且我一直得到相同的错误。然而,您回复中的第一句话帮助我找到了解决方案。我从RefreshAttendees()中删除了'async Task'签名,因为它是多余的,即在任何其他地方都没有使用await调用它。有了这个RealmInstance现在在MainThread上运行,所以我在ScanResults方法中使用了Device.BeginInvokeOnMainThread。这让它工作了。将您的回复标记为答案。干杯! - Noel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接