如何修复 Android 上的“只有创建视图层次结构的原始线程才能触摸其视图”Xamarin Forms

Mar*_*rbu 3 forms multithreading android xamarin

我正在使用 Xamarin Forms 构建一个应用程序,但仅限于 Android。当我运行应用程序时,出现此错误“只有创建视图层次结构的原始线程才能触摸其视图”。我的应用程序中有类似的页面,但这是我第一次收到此错误。我知道这是关于 UI 线程的问题,但我无法弄清楚我到底在哪里使用了错误的线程。

这是错误来源的代码:

--视图模型--

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinApp.Services;
using XamarinApp.Views.Month;

namespace XamarinApp.ViewModels.Month
{
    public class HistoryViewModel : BaseViewModel
    {
        private readonly IMonthService _monthService;
        private ObservableCollection<int> years;
        private ObservableCollection<int> months;
        public int year;
        public int month;
        public HistoryViewModel(IMonthService monthService)
        {
            _monthService = monthService;
            Years = new ObservableCollection<int>();
            Months = new ObservableCollection<int>();
            Title= "History";
            FindCommand = new Command(async () => await GoToYearHistory());
        }
        private async Task GoToYearHistory()
        {
            if (year == 0)
                return;
            await Shell.Current.GoToAsync($"{nameof(YearHistoryPage)}?{nameof(YearHistoryViewModel.Year)}={year}");
        }
            
        public async void GetYearsAndMonths()
        {

            Years.Clear();
            Months.Clear();

            var years = await _monthService.GetYears().ConfigureAwait(false);
            foreach (var year in years)
            {
                Years.Add(year);
            }

            for (int i = 0; i < 12; i++)
            {
                Months.Add(i+1);
            }
           

        }
        
        public ObservableCollection<int> Years
        {
            get => years;
            set
            {
                years = value;
                OnPropertyChanged(nameof(Years));
            }
        }

        public ObservableCollection<int> Months
        {
            get => months;
            set
            {
                months = value;
                OnPropertyChanged(nameof(Months));
            }
        }


        public int Year
        {
            get => year;
            set
            {
                year = value;
                OnPropertyChanged(nameof(Year));
            }
        }
        public int Month
        {
            get => month;
            set
            {
                month = value;
                OnPropertyChanged(nameof(Month));
            }
        }

        public ICommand FindCommand { get; }
    }
}
Run Code Online (Sandbox Code Playgroud)

---Xaml文件---

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:month="clr-namespace:XamarinApp.ViewModels.Month" x:DataType="month:HistoryViewModel"
             x:Class="XamarinApp.Views.Month.HistoryPage"
             BackgroundColor="{StaticResource BackgroundColor}">
    <ContentPage.Content>
        <StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
            <Label Text="History" 
               FontSize="Title" 
               TextColor="{StaticResource Primary}" 
               FontAttributes="Bold"
                HorizontalTextAlignment="Center"
            VerticalTextAlignment="Center" />
            <StackLayout Orientation="Horizontal">
                <Picker Title="Select Year" ItemsSource="{Binding Years}"
                                SelectedItem="{Binding Year}"  HorizontalOptions="FillAndExpand"/>
                <Picker Title="Select Month" ItemsSource="{Binding Months}"
                                SelectedItem="{Binding Month}"  HorizontalOptions="FillAndExpand"/>
            </StackLayout>
            <Button Text="Find" Command="{Binding FindCommand}" Margin="20,40,20,0" CornerRadius="10" HorizontalOptions="FillAndExpand"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Run Code Online (Sandbox Code Playgroud)

---Xaml.cs文件---


using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XamarinApp.ViewModels.Month;

namespace XamarinApp.Views.Month
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class HistoryPage : ContentPage
    {
        private readonly HistoryViewModel _historyViewModel;
        public HistoryPage()
        {
            InitializeComponent();
            _historyViewModel = Startup.Resolve<HistoryViewModel>();
            BindingContext = _historyViewModel;
        }

        protected override void OnAppearing()
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                _historyViewModel?.GetYearsAndMonths();
            });
           

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*rbu 6

因此,我通过从“varyears=await_monthService.GetYears().ConfigureAwait(false)”行中删除ConfigureAwait(false)来解决这个问题,因为ConfigureAwait(false)使我无法停留在UI线程上。