Xamarin C#开发中MessagingCenter发送的用户数据无法被接收是什么原因
问题根因
1. 消息发送时机顺序错误
你当前的代码先执行页面跳转await Shell.Current.GoToAsync($"//{nameof(FeedPage)}"),跳转完成后才发送MessagingCenter消息。await会等待跳转操作完全执行完毕才会走后续的Send逻辑,这时候会出现两种情况:
- 如果
CoinPage是跳转流程中才会初始化的页面,发送消息时CoinPage还没有执行构造函数,未完成消息订阅,消息发出去没有接收方,等CoinPage初始化完成订阅时,消息已经发送过了,自然收不到 - 即使
CoinPage之前已经初始化过,也可能因为页面跳转时的生命周期问题,订阅被临时取消/失效,导致错过消息
2. 跳转目标与订阅页面不匹配
你登录成功后跳转到的是FeedPage,如果此时你没有主动打开过CoinPage,CoinPage的构造函数永远不会执行,对应的MessagingCenter.Subscribe订阅逻辑根本没有注册,不可能接收到消息。
3. 用户名查询逻辑存在隐患,可能发送的user本身就是null
你判断用户存在时用的是完全匹配:x => x.UserName.ToLower() == userNameEntry.Text.ToLower(),但实际查询用户用的是模糊匹配x => x.UserName.ToLower().Contains(userNameEntry.Text.ToLower())。如果存在多个用户名包含输入字符串的用户,Find只会返回第一个匹配项,极端情况下甚至可能出现Exists判断为true但Find返回空的异常情况,导致你发送的user本身就是null。
修复方案
- 调整消息发送顺序,先发消息再跳转页面:
把登录逻辑里的代码顺序调换:
else { // 先发送消息 MessagingCenter.Send(user, "CurrentUser"); // 再执行跳转 await Shell.Current.GoToAsync($"//{nameof(FeedPage)}"); userNameEntry.Text = null; passwordNameEntry.Text = null; }
- 统一用户查询逻辑,避免拿到空用户:
把Find的匹配逻辑改成和Exists一致的完全匹配:
user = users.Find(x => x.UserName.ToLower() == userNameEntry.Text.ToLower());
- 如果需要在未打开的页面也能拿到用户信息,建议直接用全局静态变量存当前用户更适配你当前的需求:
新建一个静态类存储全局状态即可:
public static class AppGlobalData { public static User CurrentLoginUser { get; set; } }
登录成功后直接赋值:AppGlobalData.CurrentLoginUser = user;,其他页面任何时候需要用直接取AppGlobalData.CurrentLoginUser即可,不需要订阅消息,逻辑更简单不容易出错。
内容的提问来源于stack exchange,提问作者NubianFlamaryu
相关产品推荐
相关产品推荐

