6.1 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