Creative Commons License

Community

공지/뉴스
지식공유
질문/답변
자료실
자유로운 글
방명록

공유를 넘어 교류로... 제가 알리는 말씀 및 사이트 이용자들이 함게 참여하는 커뮤니케이션 공간입니다.

.

질문/답변

개발 중 막히셨나요?? 여기 먼저 경험한 개발자들의 답변을 부탁드려보세요~ 단, 질문의 내용은 되도록이면 아주(?) 상세히 해 주셔야 합니다

비동기화에 대해서요 질문좀요...

작성자 연습생
작성일 2008-07-11 오전 10:07:58,    조회수 : 2596

 안녕하세요^^*

backgroundworker와 Thread를 이용하여 비동기로 구동을 하는 것을 테스트해보았습니다..

첨부파일에 예를 올렸구요~~

폼1이 있으면 폼2를 호출하여 폼2에서 버튼을 누르면 텍스트박스에 숫자가 올라가는것입니다..

크로스스레드문제는 Invoke를 써서 해결이 되서 다행이었지만..

처음 폼을 호출해서 TEST를 하면 숫자가 빠르게 한개씩올라가는것을(물론... 너무빨라서 확인은 안되지만 올라가는

것 같음)확인하였습니다... 근데 폼을 한개 더 띠위서 TEST를 하면 숫자가 내부적으로는 수행이 되지만 그것을 뿌려

주지 못하는것 같습니다... 보여지는것이 예를 들어 200이다 다음은 230 뭐 이런식으로 보여지더라구요

컴퓨터도 점점 느려지는것 같구요....

혹시 너무 빨라서 그런가 하고 중간에 THREAD.Sleep를 넣었더니... 해결은 되엇지만...

혹시 왜 그런지... 크로스스레드를 피하기 위해 INVOKE를 써서 그런건지.. 궁금해서요..

속도를 안줄이고...(SLEEP)해결할 수 있는 방안이 있는지.. 궁금합니다~~~

그럼 좋은 하루 되시구요~~ (___)

 

 

∵Commented by 박종명 at 2008-07-11 오전 11:56:44  
안녕하세요.. 여러가지 시도하시는 모습이 보기 좋네요 ^^
일단 님께서 작성하신 프로그램은 (물론 테스트를 위한 코드겠지만) ,
종료조건없는 무한루프에다가 중간 대기 없이 계속해서 실행되어야 하는 아주~ 무거운 코드입니다. 게다가 계속적으로 UI에 값을 갱신하기까지...
실제 이러한 코드가 작성되는 곳이 있을지, 그리고 그렇게 되어서도 안된다는 개인적인 생각을 해 봅니다... (개인적 사설입니다)

하나의 폼만 실행시켜도 UI Thread 와 Worker Thread 가 서로 제어권을 주고 받습니다.
게다가 두개 이상의 폼을 띄우면 더억 제어권 싸움(?)이 치열해 지겠네요..
이럴 경우 명시적으로 제어권을 넘겨주는 편이 좋습니다.
님께서는 Thread.Sleep(10)으로 하셨는데 10까지는 필요없구 1 정도만 해도 시스템에게는
아주 긴시간이므로 충분하리라 보입니다. 실제 1로 할경우 cpu 점유율이 거의 없음을 확인하실 수 있을 것입니다.
만일 1 millsecond 마저 허용처 못하겠다면 0으로 설정하는 것도 좋으리라 보입니다.
Thread.Sleep(0)은 대기시간 보다는 다른 Thread 가 실행되도록 제어권을 넘기는 역할을 합니다. 단 1 과 0 으로 할 때의 CPU 점유율을 유심히 보시길 바랍니다.

그리고, 다음 코드에서 backgroundworker 객체를 다시 생성하실 필요 없습니다.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker backgroundworker = new BackgroundWorker();
e.Result = this.add(100, backgroundworker, e);
}
즉, 다음처럼 수정하십시요.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = this.add((int)e.Argument, worker, e);
}

마지막으로 add메서드를 다음과 같이 작성했습니다.
public int add(int value, BackgroundWorker worker, DoWorkEventArgs e)
{
while (true)
{
if (worker.CancellationPending)
{
e.Cancel = true;
}
else
{
this.Invoke(new procControl(this.BindingTextBox), new object[] { (value++).ToString() });
System.Threading.Thread.Sleep(0);
}
}
}
∵Commented by 연습생 at 2008-07-11 오후 2:09:17  
ㅇ ㅏㅎ ㅏ~~ 그런 이유가 ㅎㅎ 바쁘신데 답변 감사드립니다~
그럼 비동기를 주면 dowork이벤트가 발생하면서 add()메소드가 비동기를 이루는 거죠??
backgroundWorker는 매개변수도 자유롭게 주고.. 작업관리자창의 스레드도 잡아먹는것이
없던데... THread를 이용하여 비동기를 구현하기보다.. 수월하고 기능이 우수하다고 볼수있네요..(허접의 생각..;;)
∵Commented by 박종명 at 2008-07-11 오후 2:17:01  
단순히 주어진 문제만 급급히 해결하는 것이 아닌 다양한 접근 방법과 그에 따른 차이점, 원리적 이해를 하시고자 하는 모습이 아주 좋아 보이십니다 ^^
이 참에 멀티쓰레딩 프로그래밍에 대해 보다 심도있게 공부해 보심이 어떠실런지요?
그리고 공부하고 경험한 내용을 이 사이트에 공유해 주시면 더욱 좋구요 ㅋㅋ
여튼 화이팅입니다~
∵Commented by 연습생 at 2008-07-11 오후 5:39:01  
스레드의 슬립여부에 따라 CPU사용이... 정말 다르네요.. 컴터한테는 정말 작은 시간이라도 많은 작업을 하나봐요 계속 공부를 하겠지만.. 그나마 약간 이사이트에서 많은 것을 배우고 활용하고 있습니다 감사드리구요~~ 좋은 하루되세요 (__)
∵Commented by 연습생 at 2008-07-11 오후 5:46:52  
ㅠㅜ 질문이 좀 이상하게 해서.. 다시 할려고 하는차에...답변을 ㅠㅜ
일단..몰랐던 부분까지 알아서 너무 감사합니다~~ 그러면 backgroudworker를 CancelAsync로 멈추게 하고 다시 실행을 하면 숫자가 다시 처음부터 시작하는 것을 확인할 수 있는데 이것은
이전에 만들었던 것은 해제를 하고 다시 생성을 했다고 생각을 해도 되겠죠? CancelAsync를 호출함으로써 메모리를 해제하고 그것을 가비지가 나중에 처리를 하는거겠죠??(허접의 생각)
파고들수록.. 허접한 상식이 바닥을 ㅎㅎㅎ
∵Commented by 박종명 at 2008-07-11 오후 6:00:35  
저도 답변을 달고 나니, 질문이 없어져서 지웠네요 ^^;

Backgroundworker 의 CancelAsync 를 통해 중지하시면 비동기 작업이 중지되는 것입니다.
그리고 다시 시작을 하면 동일한 Backgroundworker 객체로 비동기 작업을 다시 시작하구요..
이때 작업 시작시 시작값을 설정하기 때문에 다시 처음부터 숫자가 시작되는 거구요.
만일 클래스변수로 숫자를 저장할 경우에는 이후 값 부터 시작할 수 있겠죠.

CancelAsync 로 취소하던 아니던지(수행중에도) 간에 매번 전달 값 string text 는 계속적으로 unreachable object 가 되어 가비지수집기의 수집 대상이 됩니다.
(아시다시피 string도 참조타입이니깐요)
∵Commented by 연습생 at 2008-07-11 오후 6:31:02  
앗 ㅈㅅ합니다 (__) ㅎㅎ 이제 퇴근을 할려는 찰라.. ㅎㅎㅎ 의문점이.. 들었습니다...
이 답변은.. 월요일날 달아주셔두 되요^^*
Backgroundworker를 이용하면 작업관리자의 스레드 부분의 증가가 없는 것을 확인할 수 있었습니다. THREAD를 이용하면 스레드가 증가가 되구요.. 자신이 세운 스레드때문에 스레드증가가 되면 속도의 차이가 없는데 다른 프로그램(인터넷,프로그램등등)에 의해 증가가 되면 속도에서 차이가 나더라구요..이거 역시 권한을 주고 받고하는 과정에서 생기는 현상이죠?
그럼 정말 좋은 주말 보내시구요~~(__)
∵Commented by 박종명 at 2008-07-14 오전 10:00:53  
좋은 아침입니다~ 모든 프로그램의 기능은 메모리에 올라가 있어야 cpu가 실행을 할 수 있습니다. 단일 CPU 에서 다중 쓰레드를 번갈아 가며 작업을 할 경우 메모리에 해당 작업들을 번갈아 가면서 올렸다 내렸다 해야 합니다. 이것을 컨텍스트 스위칭이라고 하는데요, 이 작업은 분명히 적지않은 시스템 비용이 발생하는 부분입니다. 운영체제와 관련된 서적을 읽어 보시길 권장드립니다.
이름
비밀번호
홈페이지
YU <- 왼쪽의 문자를 오른쪽 박스에 똑같이 입력해 주세요