개발일기/C#

[C#] 비동기 프로그래스바.

쌀덕이 2014. 5. 30. 14:57

ProgressBar에 Value값을 입력하면 


Value값까지 증가값만큼 순차적으로 증가한다.


C# 4.0환경에서 작성했으며..


3.0이상이면 무리없이 작동할거라고 생각된다...ㅎㅎ


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
 
namespace AsyncProgressBar
{
    /// <summary>
    /// 컴포넌트의 값을 비동기적으로 설정된 증가값만큼 증가시켜준다.
    /// </summary>
    public partial class AsyncProgressBar : ProgressBar, IProgressCompleted, IProgressChanged
    {
        private delegate void Increasing();
 
        /// <summary>
        /// 증가값
        /// </summary>
        [DefaultValue(1)]
        public int Increase
        {
            get;
            set;
        }
 
        private int m_value;
        /// <summary>
        /// 현재값
        /// </summary>
        public new int Value
        {
            get { return m_value; }
            set
            {
                if (value > 0)
                {
                    m_value = value;
                    if (m_value == 0)
                    {
                        base.Value = 0;
                    }
                    else
                    {
                        if (!_worker.IsBusy)
                            _worker.RunWorkerAsync();
                    }
                }
            }
        }
 
        //백그라운드 작업 객체
        BackgroundWorker _worker = new BackgroundWorker();
 
        public AsyncProgressBar()
            : base()
        {
            InitializeComponent();
            if (this.Increase < 1)
                this.Increase = 1;
            
            _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
        }
 
        void _worker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (isEnableIncre())
            {
                base.Invoke(new Increasing(delegate
                {
                    base.Value = base.Value + this.Increase;
                    //값이 증가되면 상태변경 이벤트 호출
                    OnProgressChanged(base.Value);
                    Thread.Sleep(10);
                }));
            }
 
            //Value가 최대값에 도달. 완료 이벤트 호출
            if (this.Maximum == base.Value)
            {
                OnProgressCompleted();
            }
        }
 
        /// <summary>
        /// 컴포넌트의 Value 값을 증가시킬수있는지 확인한다.
        /// </summary>
        /// <returns></returns>
        private bool isEnableIncre()
        {
            return base.Value < this.Value && this.Value >= 0;
        }
 
        /// <summary>
        /// 프로그래스 값이 변경된것을 알려준다.
        /// </summary>
        /// <param name="nCrnt"></param>
        private void OnProgressChanged(int nCrnt)
        {
            if (ProgressChanged != null)
            {
                ProgressChanged(new ProgressChangedEventArgs(nCrnt));
            }
        }
 
        /// <summary>
        /// 프로그래스가 완료된것을 알려준다.
        /// </summary>
        private void OnProgressCompleted()
        {
            if (ProgressCompleted != null)
            {
                ProgressCompleted(new ProgressCompletedEventArgs());
            }
        }
 
        /// <summary>
        /// 프로그래스 값이 변경된것을 알려준다.
        /// </summary>
        public event ProgressCompletedHandler ProgressCompleted;
 
        /// <summary>
        /// 프로그래스가 완료된것을 알려준다.
        /// </summary>
        public event ProgressChangedHandler ProgressChanged;
 
    }
 
    #region 프로그래스 변경/완료 이벤트 클래스
 
    public delegate void ProgressCompletedHandler(ProgressCompletedEventArgs e);
    public class ProgressCompletedEventArgs : EventArgs
    {
        public ProgressCompletedEventArgs()
            : base()
        {
        }
    }
    public interface IProgressCompleted
    {
        event ProgressCompletedHandler ProgressCompleted;
    }
 
 
 
    public delegate void ProgressChangedHandler(ProgressChangedEventArgs e);
    public class ProgressChangedEventArgs : EventArgs
    {
        /// <summary>
        /// 현재 값
        /// </summary>
        public int Current
        {
            get;
            private set;
        }
 
        public ProgressChangedEventArgs(int nCrnt)
            : base()
        {
            Current = nCrnt;
        }
    }
    public interface IProgressChanged
    {
        event ProgressChangedHandler ProgressChanged;
    }
    #endregion
 
}