일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- UX베이커리
- MIX10
- 마이크로소프트
- 소년포비
- 스마트폰
- 윈모데브
- 데브피아
- 옴니아2
- 김춘배
- 윈도데브
- 윈도우 모바일
- 거제도
- 윈도우모바일
- 실버라이트 코리아
- 신석현
- 서진호
- 쉐어포인트코리아
- winmodev
- 소년포비소프트
- 신동혁
- 주신영
- 안드로이드
- 황광진
- 윈도우폰
- 지승욱
- windows mobile 6.5
- 훈스닷넷
- 헤이맨
- 루나네스
- 윈도우폰7
- Today
- Total
소년포비의 세계정복!!
[c#]Thread를 이용한 파일복사하기-프로그래스바 본문
이 어플리케이션은 파일을 복사하는 기능을 가지고 있는 프로그램으로 복사하는 진행과정을 표시하기 위해서 프로그래스바(ProgressBar)컨트롤을 이용하였으며, 실제 파일이 복사되는 작업은 스레드(Thread)로 처리하여 복사작업과 진행상태작업이 동시에 이루어지도록 했습니다.
그리고 이프로그램은 그림에서 알 수 있듯이 두 개의 폼으로 구성되어 있습니다. 첫번째 폼(Form1)은 복사할 원본과 대상을 지정하는 폼이고, 두번째 폼(DownDialog)은 복사 진행상황을 보여주는 폼입니다. 다음 소스를 통해서 각 폼에서 처리할 일들을 알아보도록 하겠습니다.
/////////////////////////////////////
// Form1
/////////////////////////////////////
복사버튼을 클릭하면 발생하는 핸들러로서 DownDialog폼을 생성하여 화면에 출력하는 기능을 가진 함수입니다.
private void btnExecute_Click(object sender, System.EventArgs e)
{
// 원본과 대상파일명이 있는 텍스트박스의 Text속성값을 생성자의 전달인자로 사용
DownDialog dlg = new DownDialog(txtSrc.Text, txtDest.Text);
dlg.Show();
}
///////////////////////////////////////
// DownDialog
///////////////////////////////////////
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
using System.IO;
namespace Thread
{
public class DownDialog : System.Windows.Forms.Form
{
// 스레드 생성과정에서 서로 다른 프로세스에 접근을 위해서 필요한 델리깃 선언
public delegate void SetProgCallBack(int vv); // 진행바 값을 보내기 위한 델리깃
public delegate void SetLabelCallBack(string str); // 진행률을 보내기 위한 델리깃
public delegate void ExitCallBack(); // 복사완료 후 창 종료를 위한 델리깃
private System.Threading.Thread t1; // 스레드 선언
private byte [] bts = new byte[4096]; // 파일스트림으로 주고받을 기본단위
private FileStream fsSrc = null; // 원본파일 스트림
private FileStream fsDest = null; // 대상파일 스트림
public DownDialog(string src, string dest) {
InitializeComponent();
// 해당 파일을 파일 스트림 객체로 생성
fsSrc = new FileStream(src, FileMode.Open, FileAccess.Read); //읽기
fsDest = new FileStream(dest, FileMode.Create, FileAccess.Write); //쓰기
}
private void DownDialog_Load(object sender, System.EventArgs e) {
progressBar1.Maximum = 100; // 진행바의 최대값 100으로 설정
// 스레드 생성
t1 = new System.Threading.Thread(new ThreadStart(DownLoad));
t1.Start(); // 스레드 시작
}
// t1 스레드에서 만들어진 값(vv)을 메인스레드(폼)의 진행바컨트롤에 지정하기 위한 메소드
private void SetProgBar(int vv) {
// 서로다른 프로세스에서 객체를 크로스로 접근하면 예외가 발생하므로 이를 해결하기
// 위해서 Invoke 메소드 사용하게 된다.
// 진행바가 현재 Invoke가 필요한 상태인지 파악하여 필요하다면 대기상태에 있다가
// 접근가능할 때 백그라운드 작업을 진행하고, 필요한 상태가 아니라면
// 진행바의 해당 속성에 바로 대입한다.
if(this.progressBar1.InvokeRequired) {
// 델리깃 생성
SetProgCallBack dele = new SetProgCallBack(SetProgBar);
// 대기상태에 있다가 접근가능한 상태일 때 SetProgBar 간접호출
this.Invoke(dele, new object[] { vv });
}
else
this.progressBar1.Value = vv;
}
// t1 스레드에서 만들어진 값(str)을 메인스레드(폼)의 레이블에 지정하기 위한 메소드
private void SetLabel(string str) {
if(this.label2.InvokeRequired) {
SetLabelCallBack dele = new SetLabelCallBack(SetLabel);
this.Invoke(dele, new object[] { str });
}
else
this.label2.Text = str;
}
// t1 스레드에서 메인스레드(폼)의 종료메소드(Close)를 지정하기 위한 메소드
private void Exit() {
ExitCallBack dele = new ExitCallBack(Close);
this.Invoke(dele); // 복사진행률 창 닫기
}
// 파일 복사 작업 및 진행률 구하여 값 넘기기
private void DownLoad() {
int vv = 1; // 진행바의 진행률을 저장할 변수
int cnt = 0; // 1. 반복 횟수 및 2. 파일스트림 읽거나 저장할 위치 지정 변수
while(true) {
if(vv >= 100) { // 진행률이 100이 되면 무한루프 탈출
break;
}
// 원본파일 읽을 위치지정 및 4096바이트 읽어 bts에 저장
fsSrc.Seek(4096 * cnt, SeekOrigin.Begin); fsSrc.Read(bts, 0, 4096);
// 대상파일에 쓸 위치지정 및 bts에 저장된 값 쓰기
fsDest.Seek(4096 * cnt, SeekOrigin.Begin); fsDest.Write(bts, 0, 4096);
cnt++;
vv = (int)(fsDest.Length * 100 / fsSrc.Length); // 진행률 구하기
// 메인스레드에 값넘기기
SetProgBar(vv);
SetLabel(vv + "%");
}
this.Exit(); // 메인스레드에 종료 알리기
}
}
}
'프로그램 세상 > C#' 카테고리의 다른 글
[C#] DB에 이미지저장하고 불러오기 (0) | 2009.10.12 |
---|---|
[c#] 모든 드라이브 정보 얻기? (0) | 2009.10.11 |
[C#] 윈도우 레지스트리(Registry) 읽기/쓰기/관리 (0) | 2009.10.11 |
[C#] xml 파일 읽어서 DataGrid 표시 (0) | 2009.10.11 |
[C#] 각종 데이테베이스 연결 방법 샘플 자료 (0) | 2009.10.11 |