.NET MAUI MVVM应用Android正常,Windows点击Add按钮触发内存访问异常
问题
基于.NET MAUI与CommunityToolkit.Mvvm开发的购物车示例应用,在Android模拟器上运行正常,但在Windows设备点击Add按钮时抛出以下异常:System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
已尝试清理并重建项目,但问题未解决。相关代码如下:
MainViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.Maui.Networking; using System.Collections.ObjectModel; namespace ShoppingCart.ViewModel { public partial class MainViewModel : ObservableObject { IConnectivity connectivity; public MainViewModel(IConnectivity connectivity) { items = new ObservableCollection<string>(); this.connectivity = connectivity; } [ObservableProperty] ObservableCollection<string> items; [ObservableProperty] string text; [RelayCommand] async Task Add() { if (string.IsNullOrWhiteSpace(Text)) { return; } if (connectivity.NetworkAccess != NetworkAccess.Internet) { await Shell.Current.DisplayAlert("Uh oh", "No Internet", "OK"); return; } items.Add(Text); Text = string.Empty; } [RelayCommand] void Delete(string s) { if (items.Contains(s)) { items.Remove(s); } } [RelayCommand] async Task Tap(string s) { await Shell.Current.GoToAsync($"{nameof(DetailPage)}?Text={s}"); } } }
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ShoppingCart.MainPage" xmlns:viewmodel="clr-namespace:ShoppingCart.ViewModel" x:DataType="viewmodel:MainViewModel"> <Grid RowDefinitions="100 , Auto, *" ColumnDefinitions=".75* , .25*" Padding="10" RowSpacing="10" ColumnSpacing="10"> <Image Grid.ColumnSpan="2" Source="shopping_cart2.png" BackgroundColor="Transparent"/> <Entry Placeholder="Enter Product" Text="{Binding Text}" Grid.Row="1" /> <Button Text="Add" Command="{Binding AddCommand}" Grid.Column="1" Grid.Row="1" /> <CollectionView Grid.Row="2" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" SelectionMode="None"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="{x:Type x:String}"> <Frame x:Name="frame" CornerRadius="10" Margin="10" Padding="0" HasShadow="False"> <!--adding round corner to SwipeView--> <SwipeView> <SwipeView.RightItems> <SwipeItems> <SwipeItem Text="Delete" BackgroundColor="Gray" Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}" CommandParameter="{Binding .}"/> </SwipeItems> </SwipeView.RightItems> <Grid Padding="0.5"> <Frame> <Frame.GestureRecognizers> <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=TapCommand}" CommandParameter="{Binding .}"/> </Frame.GestureRecognizers> <Label Text="{Binding .}" FontSize="20"/> </Frame> </Grid> </SwipeView> </Frame> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </Grid> </ContentPage>
解决方案
- 强制在UI线程更新集合:Windows平台对UI线程的要求更严格,即使当前看似在UI线程,也可能存在线程上下文问题。修改
Add方法中的集合添加逻辑:
// 替换原items.Add(Text); MainThread.BeginInvokeOnMainThread(() => { items.Add(Text); });
- 替换IConnectivity的使用方式:依赖注入的IConnectivity实例在Windows平台可能存在内存访问异常,改用静态实例:
// 修改ViewModel构造函数 public MainViewModel() { items = new ObservableCollection<string>(); } // 修改Add方法中的网络判断逻辑 if (Connectivity.Current.NetworkAccess != NetworkAccess.Internet) { await Shell.Current.DisplayAlert("Uh oh", "No Internet", "OK"); return; }
- 简化CollectionView的ItemTemplate布局:Windows平台对SwipeView嵌套Frame的布局组合可能存在兼容性问题,调整布局结构:
<DataTemplate x:DataType="{x:Type x:String}"> <SwipeView Margin="10"> <SwipeView.RightItems> <SwipeItems> <SwipeItem Text="Delete" BackgroundColor="Gray" Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}" CommandParameter="{Binding .}"/> </SwipeItems> </SwipeView.RightItems> <Frame CornerRadius="10" Padding="10" HasShadow="False"> <Frame.GestureRecognizers> <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=TapCommand}" CommandParameter="{Binding .}"/> </Frame.GestureRecognizers> <Label Text="{Binding .}" FontSize="20"/> </Frame> </SwipeView> </DataTemplate>
- 升级依赖库版本:该异常可能是.NET MAUI或CommunityToolkit.Mvvm的已知平台bug,将这两个库更新到最新稳定版本,修复内存访问相关问题。
内容的提问来源于stack exchange,提问作者snikos
相关产品推荐
相关产品推荐

