当前位置: 首页 > article >正文

62.异步编程+Prism

为什么不需要在构造函数中初始化了?

private ICommand _fetchUserInfoCommand;        
public ICommand FetchUserInfoCommand => _fetchUserInfoCommand ??= new DelegateCommand(ExecuteFetchUserInfoAsync);        
public MainWindowViewModel()
{
    // 无需在构造函数中显式创建命令实例,因为使用了延迟初始化(??=)
}

原本的样子:

public ICommand FetchUserInfoCommand { get; } 
public MainWindowViewModel()
 {
     FetchUserInfoCommand = new RelayCommand(async (param) => await FetchUserInfoAsync());
 }
 

在C#中,??= 是一个空合并赋值运算符,它用于为可为空的变量或具有默认值类型的变量提供一个简洁的赋值方式,当且仅当该变量当前为 null(对于引用类型)或默认值(对于值类型)时。

在Prism框架的上下文中,当你将命令属性定义为只读并希望它在首次被访问时才被创建时,可以使用 ??= 运算符来实现延迟初始化。这种方法的好处是,它避免了在构造函数中不必要的初始化开销,特别是当命令的创建涉及复杂逻辑或资源消耗时。

当你第一次尝试访问 FetchUserInfoCommand 属性时,C# 会检查 _fetchUserInfoCommand 字段是否为 null。如果是,它会执行 ??= 右侧的表达式,即创建一个新的 DelegateCommand 实例,并将其赋值给 _fetchUserInfoCommand。之后,每次访问 FetchUserInfoCommand 属性时,都会直接返回这个已经创建的命令实例,而不会再次执行初始化代码。

这种延迟初始化的技术有助于提升应用程序的性能和响应性,因为它允许你按需创建对象,而不是在应用程序启动时立即创建所有可能需要的对象。

void和Task的区别

private async void ExecuteFetchUserInfoAsync();
private async Task ExecuteFetchUserInfoAsync();

在C#中,按钮点击等事件处理常使用async void,因其需匹配返回void的委托类型。但使用async void需谨慎:它不可被await,且异常需内部处理,否则可能导致崩溃。对于非事件处理的长时间运行任务,async Task更佳,因可await其完成,用try-catch捕获异常,并支持取消。选择时,需考虑方法用途、是否需要等待、异常处理及是否事件处理。非事件处理且需等待和错误处理时,应选async Task

后台代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace 异步
{
    public class MainWindowViewModel : BindableBase
    {
        // 声明命令
        private ICommand _fetchUserInfoCommand;
        public ICommand FetchUserInfoCommand => _fetchUserInfoCommand ??= new DelegateCommand(ExecuteFetchUserInfoAsync);

        // 用户信息属性
        private string _userInfo;
        public string UserInfo
        {
            get => _userInfo;
            set => SetProperty(ref _userInfo, value); // 使用SetProperty进行属性变更通知(如果继承了BindableBase)
        }

        // 异步执行方法
        private async void ExecuteFetchUserInfoAsync()
        {
            // 模拟异步操作,比如网络请求
            await Task.Delay(2000); // 模拟网络延迟
            UserInfo = "用户信息:新员工,需要学会WPF的异步,并巩固之前的知识。";
        }

        // 构造函数
        public MainWindowViewModel()
        {
            // 无需在构造函数中显式创建命令实例,因为使用了延迟初始化(??=)
        }


    }
}
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 异步
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext=new MainWindowViewModel();
        }
    }
}

前台:

<Window x:Class="异步.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:异步"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <Button Content="获取用户信息" Command="{Binding FetchUserInfoCommand}" Margin="10"/>
            <TextBox Text="{Binding UserInfo, UpdateSourceTrigger=PropertyChanged}" Margin="10,20,10,10" TextWrapping="Wrap" Height="100"/>
        </StackPanel>
    </Grid>
</Window>


http://www.kler.cn/a/521845.html

相关文章:

  • 【python】subprocess.Popen执行adb shell指令进入linux系统后连续使用指令,出现cmd窗口阻塞问题
  • FortiOS 存在身份验证绕过导致命令执行漏洞(CVE-2024-55591)
  • USB 3.1-GL3510-52芯片原理图设计
  • TCP是怎么判断丢包的?
  • ChirpIoT技术的优势以及局限性
  • Versal - 基础3(AXI NoC 专题+仿真+QoS)
  • 数据结构实战之线性表(一)
  • 【算法】多源 BFS
  • YOLOv8:目标检测与实时应用的前沿探索
  • HTML5使用favicon.ico图标
  • android 的aab包
  • 2015年蓝桥杯第六届CC++大学B组真题及代码
  • 利用Python中Scapy库分析网络性能
  • 1月27(信息差)
  • 当高兴、尊重和优雅三位一体是什么情况吗?
  • ShenNiusModularity项目源码学习(7:数据库结构)
  • 前端监控之rrweb录制用户行为
  • 【学术会议征稿】第五届能源、电力与先进热力系统学术会议(EPATS 2025)
  • 18. 四数之和【力扣】——两层循环后的双指针法
  • 开启eslint后,html中全角符号绕过eslint检测
  • .NET Core 中依赖注入的使用
  • 上位机知识篇---CMake
  • download-git-repo 一款命令行下载仓库依赖
  • DeepSeek崛起:中国AI新星如何撼动全球资本市场格局
  • PHP中的获取器和修改器:探索数据访问的新维度
  • H3CNE-23-vlan间路由