2011-04-05 3 views
0

일반적으로 C#과 코딩에 비교적 익숙하지 않습니다. 나는 어떤 논리를 가지고있는 프로그 램을 작성하려고하는데, 이는 또한 진행 표시 줄과 함께 진행 상황을 표시합니다. 모든 비즈니스 로직을 수행하는 Main() 스레드를 시작하고 있습니다. 그것은 진행 막대가 udpated 필요한 지점에서 trigerred 이벤트가 있습니다.C# Winform 다중 스레드 시퀀스

Form 개체는 비즈니스 논리 이벤트를 구독하고 진행률 막대 및 텍스트 레이블을 업데이트하기 위해 호출되는 스레드 안전 대리인을가집니다.

제 문제는 Form이 주 스레드에서 시작되므로 Application.Run() 전에 비즈니스 로직 스레드를 시작해야한다는 것입니다. 첫 번째 ProgressUpdate 이벤트가 trigerred되면 Form 개체가 여전히 존재하지 않습니다. 내가 해킹하는 방법은 Thread.Sleep (100) 두 번째 스레드에 추가하는 것,하지만 나는 그것을 좋아하지 않아. 이 문제를 어떻게 해결할 수 있습니까? 완전히 잘못된 트랙에 있습니까? (심지어 의미가 있습니까?)

 Form1 theForm = new Form1(); 
     CreateReport theCreateReport = new CreateReport(); 
     Thread t = new Thread(new ThreadStart(theCreateReport.DoProcess)); 
     t.IsBackground = true; 
     theForm.Subscribe(theCreateReport); 
     t.Start(); 
     Application.Run(theForm); 

theForm은 양식입니다. theCreateReport는 비즈니스 로직이 시작되는 곳입니다.

답변

0

Form은 (첫 번째 줄에) 생성자를 호출 한 후에 이미 존재합니다. 아직 보이지 않습니다. 따라서 걱정할 필요가 없습니다. 새 스레드를 시작할 때 모든 것이 초기화됩니다.

+0

그래서 기본 VC# S 프로젝트에서 생성자를 나눠 줬습니다. 그래도 작동하지 않는 것 같습니다. 개체가 만들어지기 전에 Invoke/BeginInvoke를 사용해서는 안된다는 오류가 나타납니다. try catch 블록을 빈 캐치로 놓으면 작동하지만 해킹처럼 느껴집니다. 그것은 내가 까다로울 수 있습니다. – whatsinaname

+0

해킹입니다. .Net의 양식 기반 응용 프로그램은 기본적으로 기본 양식 개념을 기반으로합니다. 프로젝트가 이미 기본 폼을 사용하기 때문에이 것을 싸울 이유가 없습니다. – MusiGenesis

+0

포마 (Poma)가 언급했듯이이 형식은 이미 존재했기 때문에 이것을 대답으로 표시합니다. 오류는 내 코드의 다른 섹션에 있습니다. 고맙습니다. – whatsinaname

1

아마도 OnLoad 이벤트에서 비즈니스 로직을 시작해야합니까?

4

비즈니스 논리 스레드 대신 하나 이상의 개체를 사용하려고합니다. 이렇게하면 스레딩을 관리 할뿐만 아니라 메인 스레드에 진행 피드백을 제공 할 수있는 방법을 제공합니다.

+0

Form1() 메서드 내에서 스레드를 시작하면 어떻게 다릅니 까? 나는 이미 제 손잡이와 대의원을두고 있습니다. Form 내에서 모든 비즈니스 로직을 시작/수행하는 것이 좋은 프로그래밍 습관입니까? 내가 언급했듯이 여기에 완전한 초보자이다. 감사. – whatsinaname

+0

이미 작동하는 것이 있다면 꼭 사용하십시오. BackgroundWorker는 개별 스레드를 관리하지 않고도 별도의 스레드를 다른 스레드로 던져 나중에 결과를 얻는 쉬운 방법을 제공합니다. – geofftnz

0

Main에서 양식을 작성하면 Application.Run이됩니다. 양식의 Load 이벤트에서 스레드를 시작하십시오.

당신이 현재하고있는 방식대로 일을하면 실제로 이점을 얻지 못합니다. 그리고 이미 발견했듯이 타이밍/시퀀스 문제가 발생합니다.

문제를 해결하는 가장 좋은 방법은 문제를 해결하는 것입니다.

+0

GUI와 비즈니스 로직을 완전히 분리하는 것이 바람직하다고 들었습니다. (GUI 메서드 내에서 비즈니스 로직 스레드를 시작하는 대신). 그 작업은 내가 함께 일하는 Java 개발자로부터 온 것입니다. 그래서 C# 코딩의 경우에 적용되는지 모르겠습니다. – whatsinaname

+0

GUI와 비즈니스 로직의 분리는 다른 객체가 실행되는 스레드보다 코드가 구성되는 방식과 관련이 있습니다. 일반적으로 말하자면, 다중 스레드 응용 프로그램은 단일 스레드보다 덜 신뢰할 수 있습니다. 코드를 통한 경로가 스레드 스케줄러의 제어하에 놓이기 때문에 예측이 쉽지 않기 때문입니다. 다중 스레딩의 고유 한 위험을 필요로하는 합법적 인 이유가 있습니다. (수행중인 작업을 아는 경우이 작업을 안전하게 수행 할 수 있습니다.)하지만 3 계층 정통을 준수하는 것은 실제로 그 중 하나가 아닙니다. – MusiGenesis

0

BackgroundWorker를 사용하고 이벤트와 대리자를 계속 사용할 수 있습니다. 이번에는 Background Worker의 "ProgressChanged"및 "RunWorkerCompleted"이벤트를 마무리하고 처리 할 것입니다.

그리고 양식은 이러한 이벤트를 수신하고 이에 따라 ProgressBar를 업데이트 할 수 있습니다.

BWorker는 GUI 스레드 및 예외 처리로의 전환을보다 잘 처리합니다.

Form Load에서 BackgroundWorker를 초기화 할 수 있습니다.