본문 바로가기
[ Program ]/C#

프로그레스바와 지금까지 걸린 시간을 동시에 표시해보자

by 관이119 2012. 9. 18.
출처 wanna be의 소프트웨어 팩토리. | 완전초짜
원문 http://blog.naver.com/netscout82/20036856643

 

이번 글은 BackGroundWorker와 System.Threading.Timer를 이용해서,

작업을 진행하면서, 프로그레스바와

지금까지 걸린 시간을 동시에 표시하는 것이다.

(VS.NET 2005와 C#2.0으로 작업)

내가 잘 못해서 그런걸 수도 있지만,

이게 쉬워보이지만, 결코 그렇지가 않다-_-;;

3시간의 삽질끝에 나온 결과물이니 우스워도 적당히 이해해주시길-_-;;;


 

 

 

이런 장면 되겠다.

우선, 코드보자.

 

13 public partial class Form1 : Form

14 {

15 public event EventHandler IncrementProgress;

16 int elapsed = 0;

17

18 TimerCallback timerDelegate;

19 AutoResetEvent autoEvent;

20 System.Threading.Timer timer1;

21

22 public Form1()

23 {

24 InitializeComponent();

25 }

26

27 void increase(object sender, EventArgs e)

28 {

29 progressBar1.Increment(1);

30 }

31

32 private void Form1_Load(object sender, EventArgs e)

33 {

34 progressBar1.Maximum = 20;

35 progressBar1.Step = 1;

36

37 IncrementProgress += new EventHandler(increase);

38 }

39

40 private void button1_Click(object sender, EventArgs e)

41 {

42 #region Initializing timer

43 timerDelegate = new TimerCallback(this.timer1_Tick);

44 autoEvent = new AutoResetEvent(false);

45 #endregion

46

47 elapsed = 0;

48

49 #region Initializing background worker

50 BackgroundWorker wkr = new BackgroundWorker();

51 wkr.DoWork += new DoWorkEventHandler(wkr_DoWork);

52 wkr.RunWorkerCompleted += new RunWorkerCompletedEventHandler(wkr_RunWorkerCompleted);

53 #endregion

54

55 timer1 = new System.Threading.Timer(timerDelegate, autoEvent, 0, 1000);

56 wkr.RunWorkerAsync();

57 }

58

59 #region BackgroundWorker Event

60 void wkr_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

61 {

62 timer1.Dispose();

63 MessageBox.Show("끝!!!");

64 }

65

66 void wkr_DoWork(object sender, DoWorkEventArgs e)

67 {

68 Test test = new Test(IncrementProgress);

69 test.DoEvent();

70 }

71 #endregion

72

73 #region Timer Event

74 public void timer1_Tick(object stateInfo)

75 {

76 this.Invoke(new MethodInvoker(delegate()

77 {

78 elapsed++;

79 lblProgress.Text = "Elapsed Time : " + elapsed.ToString() + " sec.";

80 }));

81 }

82 #endregion

83 }

 

Test클래스는 이전의 프로그레스바에서 변한게 없다.

아래쪽에 보면 포스트가 있으니 그걸 참조하시길.

18~20행은 타이머를 돌릴때 쓰일 객체들이다.

50~52행은 BackgroundWorker를 생성하고,

비동기로 실행할 메서드와 작업완료시 실행할 메서드를 연결해주는 부분이다.

55행에서 타이머를 생성하고 있고,
56행에선 비동기 작업을 실행하고 있다.

System.Threading.Timer 클래스는 따로 Start같은 메서드가 없으며,
객체가 생성되면, 생성자로 넘기는 3번째 인자에 설정한 시간만큼 대기하다가 돌아간다.

이렇게 하면, 비동기 background작업으로 작업이 진행되면서 프로그레스바가 움직이고,
지금까지 걸린 시간도 계산된다.

Test의 작업을 보면 알겠지만 for문으로 무식하게 돌리는 작업인데,
이 작업때문에 스레드로 따로 돌린다고 하더라도
작업이 끝난 후에나 타이머가 작동하는 것을 확인할 수 있었다.
그래서 찾다찾다찾은 대안이 BackgroundWorker이다.

실행해보면 알겠지만, 그럭저럭 잘 돌아간다.-_-;;

브라보-_-;;

댓글