Xamarin формы - доступ к царству из неправильного потока - PullRequest
0 голосов
/ 14 марта 2019

Может быть, мне здесь не хватает чего-то очень простого, но я все равно спрошу .....

Я использую формы Xamarin (проект .NET Standard), MVVMLight, Realm DB и сканер штрих-кода ZXing.

У меня такой реальный объект, как ...

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) для извлечения участника, несущего отсканированный регистрационный код.

    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: доступ к области осуществляется из неверного потока.

генерируется строкой ниже ....

SelectedParticipant = Players.FirstOrDefault (p => p.RegistrationCode.Equals (regCode, StringComparison.OrdinalIgnoreCase));

Я не уверен, что это неправильный поток, но любые идеи о том, как я могу получить извлечение отсканированного участника либо из уже заполненного IQueryable, либо из представления Realm напрямую, были бы очень благодарны.

Спасибо

1 Ответ

0 голосов
/ 14 марта 2019

Да, вы получаете экземпляр области в конструкторе, а затем используете его из асинхронной задачи (или потока). Вы можете получить доступ к области только из потока, в котором вы получили ссылку. Поскольку вы используете только экземпляр по умолчанию, вы можете просто получить локальную ссылку в функции (или потоке), где вы его используете. Попробуйте использовать

    Realm LocalInstance = Realms.Realm.GetInstance();

в верхней части функции и используйте это. Вам нужно будет заново создать запрос Participants, чтобы использовать тот же экземпляр, что и его источник. Это будет иметь место при использовании асинхронных задач (потоков), поэтому либо измените все, чтобы получить доступ к экземпляру по умолчанию при входе, либо уменьшите количество потоков, обращающихся к области.

Кстати, я удивлен, что вы не получаете подобную ошибку доступа изнутри RefreshParticipants() - возможно, вы на самом деле не получаете доступ к данным через RealmInstance оттуда.

...