2011-03-02 3 views
3
내가 클래스

기본 스레드 질문

public Class foo 
{ 
    public foo() 
    { 
     myclass = new myclass(param) 
     myclass.initiateState(); 
     val = myclass.getValues(); 
    } 
} 

Class.initiateState() 내가 스레드와 실행을 시작하고 싶어 내 GUI 생성자에서 실행하는 긴 과정이있는 경우, 그러나 다음 줄에 같은 클래스로 이동

일부 데이터를 다시 가져 오지만 새 스레드에서 첫 번째 행을 실행하면 완료되기 전에 실행됩니다.

이 문제를 어떻게 해결할 수 있습니까?

+5

:

public foo() { Thread workerThread = new Thread(this.DoWork); /* ... do other stuff ... */ } 

이 한 번 봐 :

private void DoWork() { myclass = new myclass(param); myclass.initiateState(); val = myclass.getValues(); } 

그런 다음 스레드로 실행되는 생성자를 변경 안녕, 당신은 GUI를 constractor 어쨌든 데이터를로드해서는 안 GUI를로드하고 q를 표시해야합니다 uickly. –

답변

11

BackgroundWorker을 작성하십시오.

DoWork 이벤트 메서드 내에서 myClass.initiateState() 호출을 추가하십시오. RunWorkerCompleted 이벤트 메서드 내부, 이것은 백그라운드 스레드에서 실행 initiateState의 원인이됩니다 myClass.getValues();

전화, 언제 완료 GUI 스레드에서 getValues을 발사합니다.

또한 C#에서는 자바와 비교하여 대문자로 메소드 이름을 시작하는 것이 일반적입니다. 그래서 방법이 InitiateStateGetValues :

+0

취소 및 진행 알림이 필요없는 경우'BackgroundWorker '를 만드는 것이 구문 오버 헤드라고 생각합니다. – Andrey

+1

@Andrey - 조금 더 길 수도 있지만, 다른 사람들을 위해 읽기가 쉽습니다. 어쨌든 그렇게 오래 걸리지는 않습니다. 그리고 그가 나중에 진척 상황 알림이 필요하다면 (그는 오랜 시간이 걸렸다 고 말했습니다) 그러한 변화를 구현하기 위해 기존의 작업을 쉽게 확장 할 수 있습니다. –

+0

+1 BackGroundWorker를 좋아합니다. –

4

가장 쉬운 방법이 할 수있는 이름이 있어야합니다

public Class foo 
{ 
    public foo() 
    { 
     myclass = new myclass(param) 
     new Action(() => myclass.initiateState()).BeginInvoke(initiateStateFinished, null) 
    } 

    private void initiateStateFinished(IAsyncResult ar) 
    { 
     val = myclass.getValues(); 
     //other actions 
    } 
} 

정도

public foo() 
    { 
     myclass = new myclass(param) 
     new Action(() => myclass.initiateState()) 
      .BeginInvoke(_ => val = myclass.getValues(), null) 
    } 
+0

이전에 Action을 많이 사용하지 않았으므로 여기에 질문이 있습니다. InitateStateFinished 메소드가 주 GUI 스레드 또는 백그라운드 스레드에서 호출됩니까? –

+0

@ Øyvind Knobloch-Bråthen 배경에 – Andrey

1

도 짧은을, 당신은 둘 다

myclass.initiateState(); 
    val = myclass.getValues(); 
을 실행하려면

새 스레드에서 (값이 반환 값 임)?

 var someBackgroundTask = new System.Threading.Tasks.Task<*return type of GetValue()*>(() => 
      { 
       myclass.initiateState(); 
       return myclass.getValue(); 
      }); 
     someBackgroundTask.Start(); 

을 나중에, 음, 결과를 얻을 수 someBackgroundTask.Result를 사용

당신은 쉽게 같은 .NET 4.0 Tasks을 사용하여 해당 작업을 수행 할 수 있습니다. 유일한 문제는 Task이 완료되었는지 확인하기 위해 기다려야합니다 (또는 주요 지점에서 확인해야 함). someBackgroundTask.IsCompleted을 사용하여 계속 작동하는지 확인하거나 완료 될 때까지 대기하려면 someBackgroundTask.Wait()을 사용할 수 있습니다.

편집 : 다시 말하면, 위의 제안이 더 좋습니다. ;)

0

주어진 예제에서 전체 foo 클래스는 별도의 스레드에서 실행되어야합니다. 다른 상황에 적용하기 위해 다른 스레드로 실행해서는 안되는 다른 것을 foo에 있다고 가정합니다.


먼저 foo에 DoWork 방법을 만들 : http://msdn.microsoft.com/en-us/library/7a2f3ay4.aspx

+2

GUI 스레드에서도 'val'을 사용하지만 OP에서 지정하지 않은 경우 문제가 발생할 수 있습니다. 내가 그것을 언급 할 것이라고 생각했다.) –