10. AsyncRelayCommand, AsyncRelayCommand<T>

1. 출처 및 참고자료
더보기
✔️ Microsoft Docs: AsyncRelayCommand 및 AsyncRelayCommand<T> (공식 문서)

관련 네임스페이스:

using CommunityToolkit.Mvvm.Input;
핵심 클래스
- AsyncRelayCommand 클래스
- IAsyncRelayCommand 인터페이스
- [AsyncRelayCommand] 소스 제너레이터 어트리뷰트
2. 개요
더보기
✔️ 작동 방식
- AsyncRelayCommand는 비동기 메서드(async Task)를 ICommand로 바인딩할 수 있도록 해주는 명령 클래스입니다.
- RelayCommand와 유사하지만, 내부에서 await를 안전하게 처리하며 UI가 멈추지 않도록 돕습니다.
- AsyncRelayCommand<T>는 매개변수를 받는 비동기 명령을 처리합니다.
✔️ 필요 이유
- WPF UI는 싱글 스레드로 작동하기 때문에, async를 제대로 처리하지 않으면 UI가 멈출 수 있습니다. AsyncRelayCommand를 쓰면 MVVM 구조에서도 비동기 호출과 UI 반응성을 안전하게 보장할 수 있습니다.
🟢 장점
- await 가능한 비동기 명령 처리 지원
- UI 멈춤 없이 백그라운드 처리
- MVVM 구조에서 명확한 명령 흐름 제공
- CanExecute 구현 가능 (ex. 실행 중에는 버튼 비활성화)
- AsyncRelayCommand<T>로 파라미터 전달도 지원
- void 리턴이 불가능 (항상 Task 필요)
- 예외 처리를 별도로 해야 함 (try-catch 또는 TaskScheduler.UnobservedTaskException)
3. 예제1 AsyncRelayCommand – 비동기 로딩 버튼
더보기


✔️ 동작 시나리오
- 버튼을 클릭하면 3초간 로딩 후 메시지 출력
📁 프로젝트 구조
AsyncRelayCommandDemo/ ├── ViewModels/ │ └── MainViewModel.cs ├── MainWindow.xaml └── MainWindow.xaml.cs
✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

public partial class MainViewModel : ObservableObject { [ObservableProperty] private bool isBusy; public IAsyncRelayCommand LoadCommand { get; } public MainViewModel() { LoadCommand = new AsyncRelayCommand(LoadDataAsync, CanLoadData); } private async Task LoadDataAsync() { IsBusy = true; await Task.Delay(3000); // 3초 대기 IsBusy = false; MessageBox.Show("데이터 로딩 완료!"); } private bool CanLoadData() => !IsBusy; }
✔️ XAML 화면 구성

xmlns:viewModels="clr-namespace:WPF_ToolKit10_01.ViewModels" Title="AsyncRelayCommand Demo" Height="200" Width="300"> <Window.DataContext> <viewModels:MainViewModel/> </Window.DataContext> <StackPanel Margin="20"> <Button Content="데이터 로딩" Command="{Binding LoadCommand}" /> <TextBlock Text="{Binding IsBusy, StringFormat=로딩 중: {0}}"/> </StackPanel> </Window><
4. 예제2 AsyncRelayCommand<T>로 매개변수 전달
더보기


✔️ 동작 시나리오
- 사용자 이름을 받아 "홍길동님 반갑습니다" 메시지 출력
📁 프로젝트 구조
AsyncRelayCommandDemo/ ├── ViewModels/ │ └── MainViewModel.cs ├── MainWindow.xaml └── MainWindow.xaml.cs
✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

public partial class MainViewModel : ObservableObject { public IAsyncRelayCommand<string> GreetCommand { get; } public MainViewModel() { GreetCommand = new AsyncRelayCommand<string>(GreetUserAsync); } private async Task GreetUserAsync(string name) { await Task.Delay(1000); MessageBox.Show($"{name}님, 반갑습니다!"); } }
✔️ XAML 화면 구성

xmlns:viewModels="clr-namespace:WPF_ToolKit10_02.ViewModel" Title="AsyncRelayCommand Demo" Height="200" Width="300"> <Window.DataContext> <viewModels:MainViewModel/> </Window.DataContext> <StackPanel Margin="20"> <TextBox x:Name="NameBox" /> <Button Content="인사하기" Command="{Binding GreetCommand}" CommandParameter="{Binding Text, ElementName=NameBox}" /> </StackPanel> </Window>
✔️ 요약 비교
항목 | RelayCommand | AsyncRelayCommand |
실행 메서드 | void | async Task |
비동기 지원 | ❌ 수동 처리 필요 | ✅ await 가능 |
중복 실행 방지 | ❌ 수동 구현 필요 | ✅ 내장 IsRunning 지원 |
매개변수 지원 | RelayCommand<T> | AsyncRelayCommand<T> |
예외 처리 | 일반적 try-catch | 필요 (Task 기반 예외 주의) |
✔️ 소스 코드
WPF_ToolKit10_01.zip
0.10MB
댓글을 사용할 수 없습니다.