欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 62.异步编程+Prism

62.异步编程+Prism

2025/6/8 10:14:13 来源:https://blog.csdn.net/S13461120713/article/details/145365998  浏览:    关键词: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>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词