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 – 비동기 로딩 버튼

더보기

✔️ 동작 시나리오

 

  1. 버튼을 클릭하면 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>로 매개변수 전달

더보기

✔️ 동작 시나리오

 

  1. 사용자 이름을 받아 "홍길동님 반갑습니다" 메시지 출력


📁 프로젝트 구조

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