2016/11/21 - [프로그램 자료/Visual C#] - Winform에서 작업하는 동안 로딩화면 띄우기
쓰레드 구현시, 완료 이벤트를 받고 싶었다.
우선 아래의 클래스를 작성해 넣는다.
스톱 기능을 추가해보았다
using System;
using System.Threading;
public class ThreadWorker
{
Thread th;
public event EventHandler DoWork;
public event EventHandler OnCompleted;
public event ProcessChangedEventHandler OnProcessChanged;
public delegate void ProcessChangedEventHandler(object sender, ProgressEventArgs e);
public void Stop()
{
th.Abort();
}
public void ReportProgress(float per)
{
if (OnProcessChanged != null)
OnProcessChanged(this, new ProgressEventArgs(per));
}
public void Run()
{
th = new Thread(Work);
th.IsBackground = true;
th.Start();
}
private void Work()
{
if (DoWork != null)
DoWork(this, EventArgs.Empty);
if (OnCompleted != null)
OnCompleted(this, EventArgs.Empty);
}
}
public class ProgressEventArgs : EventArgs
{
public ProgressEventArgs(float percent)
{
this.Percent = percent;
}
public float Percent { get; private set; }
}
위의 클래스를 가지고 예제를 꾸려보면 아래와 같다.
static ThreadWorker tw = new ThreadWorker();
tw.DoWork += Tw_DoWork;
tw.OnCompleted += Tw_OnCompleted;
tw.OnProcessChanged += Tw_OnProcessChanged;
delegate void ChangePercentDelegate(float per); //percent 델리게이트
private void Tw_OnCompleted(object sender, EventArgs e)
{
// 작업완료
}
private void Tw_DoWork(object sender, EventArgs e)
{
SearchFile(sender); //파일 검색 시작
}
private void Tw_OnProcessChanged(object sender, ProgressEventArgs e)
{
ChangePercentDele(e.Percent); // 퍼센트를 주기위한 이벤트 등록
}
private void ChangePercentDele(float per)
{
//실제 퍼센트를 화면상에서 올리는 곳
if (statusStrip1.InvokeRequired)
{
statusStrip1.Invoke(new ChangePercentDelegate(ChangePercent), new object[] { per });
}
else
ChangePercent(per);
}
private void ChangePercent(float per)
{
txtPercent.Text = (per * 100).ToString("#,###.00") + "%";
}
private void btnCancel_Click(object sender, EventArgs e)
{
// 쓰레드 종료인데 쓰레드 생성을 많이해서(Parallel.ForEach)
isStop = true;
Thread.Sleep(1000);
tw.Stop();
ControlState(false);
}
private void SearchFile(object sender)
{
// 실제 파일 찾는 부분
Stopwatch sw = new Stopwatch();
sw.Start();
Parallel.ForEach(fileList, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, (file, stateFile) =>
{
curFile++;
if (curFile % 10 == 0)
tw.ReportProgress((float)curFile / (float)totalFile); //퍼센트 보고
});
tw.ReportProgress((float)1);
sw.Stop();
Console.WriteLine("검색종료 : " + sw.ElapsedMilliseconds);
}
이전버전
class ThreadWorker
{
public Func<int> Process { get; set; } // 실제 스레드가 작업할 메소드 명
public event EventHandler OnCompleted; // 작업할 내용르
public void Run()
{
Process();
if (OnCompleted != null)
OnCompleted(this, EventArgs.Empty);
}
}
사용방법은 아래와 같다.
private void button1_Click(object sender, EventArgs e)
{
ThreadWorker worker = new ThreadWorker();
worker.Process = proc;
worker.OnCompleted += new EventHandler(Complete);
Thread thread1 = new Thread(worker.Run);
thread1.Start();
}
private int proc()
{
for (int i = 0; i < 5000; i++)
{
Console.WriteLine(i);
}
return 0;
}
private void Complete(object sender, EventArgs e)
{
MessageBox.Show("complete");
}