프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / ConvertService / ServiceBase / Markus.Mvvm.ToolKit / AsyncCommand / AsyncCommand.cs @ 765fe3f1

이력 | 보기 | 이력해설 | 다운로드 (3.12 KB)

1
using System;
2
using System.Threading.Tasks;
3
using System.Windows.Input;
4

    
5
namespace Markus.Mvvm.ToolKit
6
{
7
    public class AsyncCommand : IAsyncCommand
8
    {
9
        public event EventHandler CanExecuteChanged;
10

    
11
        private bool _isExecuting;
12
        private readonly Func<Task> _execute;
13
        private readonly Func<bool> _canExecute;
14
        private readonly IErrorHandler _errorHandler;
15

    
16
        public AsyncCommand(
17
            Func<Task> execute,
18
            Func<bool> canExecute = null,
19
            IErrorHandler errorHandler = null)
20
        {
21
            _execute = execute;
22
            _canExecute = canExecute;
23
            _errorHandler = errorHandler;
24
        }
25

    
26
        public bool CanExecute()
27
        {
28
            return !_isExecuting && (_canExecute?.Invoke() ?? true);
29
        }
30

    
31
        public async Task ExecuteAsync()
32
        {
33
            if (CanExecute())
34
            {
35
                try
36
                {
37
                    _isExecuting = true;
38
                    await _execute();
39
                }
40
                finally
41
                {
42
                    _isExecuting = false;
43
                }
44
            }
45

    
46
            RaiseCanExecuteChanged();
47
        }
48

    
49
        public void RaiseCanExecuteChanged()
50
        {
51
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
52
        }
53

    
54
        #region Explicit implementations
55
        bool ICommand.CanExecute(object parameter)
56
        {
57
            return CanExecute();
58
        }
59

    
60
        void ICommand.Execute(object parameter)
61
        {
62
            ExecuteAsync().FireAndForgetSafeAsync(_errorHandler);
63
        }
64
#endregion
65
    }
66

    
67
	public class AsyncCommand<T> : IAsyncCommand<T>
68
    {
69
        public event EventHandler CanExecuteChanged;
70

    
71
        private bool _isExecuting;
72
        private readonly Func<T, Task> _execute;
73
        private readonly Func<T, bool> _canExecute;
74
        private readonly IErrorHandler _errorHandler;
75

    
76
        public AsyncCommand(Func<T, Task> execute, Func<T, bool> canExecute = null, IErrorHandler errorHandler = null)
77
        {
78
            _execute = execute;
79
            _canExecute = canExecute;
80
            _errorHandler = errorHandler;
81
        }
82

    
83
        public bool CanExecute(T parameter)
84
        {
85
            return !_isExecuting && (_canExecute?.Invoke(parameter) ?? true);
86
        }
87

    
88
        public async Task ExecuteAsync(T parameter)
89
        {
90
            if (CanExecute(parameter))
91
            {
92
                try
93
                {
94
                    _isExecuting = true;
95
                    await _execute(parameter);
96
                }
97
                finally
98
                {
99
                    _isExecuting = false;
100
                }
101
            }
102

    
103
            RaiseCanExecuteChanged();
104
        }
105

    
106
        public void RaiseCanExecuteChanged()
107
        {
108
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
109
        }
110

    
111
#region Explicit implementations
112
        bool ICommand.CanExecute(object parameter)
113
        {
114
            return CanExecute((T)parameter);
115
        }
116

    
117
        void ICommand.Execute(object parameter)
118
        {
119
            ExecuteAsync((T)parameter).FireAndForgetSafeAsync(_errorHandler);
120
        }
121
#endregion
122
    }
123

    
124
}
클립보드 이미지 추가 (최대 크기: 500 MB)