2008-10-15 3 views

답변

10

UI 스레드 자체가 아닌 다른 스레드에서 UI를 업데이트하지 않는다는 일반적인 경험 법칙이 있습니다. BackgroundWorker의 기능을 사용하는 것은 좋은 생각이지만 다른 스레드에서 어떤 일이 일어나고 싶지 않거나 "Invoke"또는 BeginInvoke를 수행하여 델리게이트가 UI 스레드에서 메서드를 실행하도록해야합니다.

편집 : 존 B는 의견이 좋은 지적을했다 :

이 호출은()() 동기 및 BeginInvoke입니다 비동기 있음을 유의하십시오. Invoke()를 사용하는 경우 은 교착 상태가 발생하지 않도록주의해야합니다. 나는 BeginInvoke()가 정말로 필요하지 않다면 추천 할 것이다 동기가되는 호출.

몇 가지 간단한 예제 코드 :

// Updates the textbox text. 
private void UpdateText(string text) 
{ 
    // Set the textbox text. 
    m_TextBox.Text = text; 
} 

public delegate void UpdateTextCallback(string text); 

// Then from your thread you can call this... 
m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText), 
    new object[]{"Text generated on non-UI thread."}); 

위의 코드는 그것을 herehere 더 긴 연루에 대한 질문에서입니다.

+0

정확히 m_TextBox.Invoke는 무엇을합니까? 델리게이트가 UI 스레드에서 강제로 실행됩니까? – Yttrium

+4

정확히. Invoke()는 동기식이며 BeginInvoke()는 비동기식입니다. Invoke()를 사용하는 경우 교착 상태가 발생하지 않도록주의해야합니다. BeginInvoke()를 사용하면 정말 동기식 호출이 필요하지 않는 한 권하고 싶습니다. –

+0

Jon B. 선생님, 잘 부탁드립니다. 나는 그 요점을 반영하도록 편집 할 것이다. –

5

왜 당신은 BackgroundWorker를 사용하여 그것을하고 싶지 않으십니까? ProgressChanged라고하는 환상적인 콜백 이벤트가있어서 UI 스레드가 업데이트에 대해 알 수있게되어 Progess 바 타입 업데이트 등에 적합합니다.

link to details

1

herehere이 관련 토론이있다.

기본적으로 Invoke를 사용하여 수행합니다.

행운을 빈다.

1

또한 Invoke를 호출 할 때 InvokeRequired (VS2008에만 해당)를 고려할 것입니다. 별도의 스레드에서 UI를 업데이트하지 않는 경우가 있습니다. 델리게이트 생성 등의 오버 헤드를 줄입니다.

if (InvokeRequired) 
     { 
      //This.Invoke added to circumvent cross threading exceptions. 
      this.Invoke(new UpdateProgressBarHandler(UpdateProgressBar), new object[] { progressPercentage }); 
     } 
     else 
     { 
      UpdateProgressBar(progressPercentage); 
     } 
관련 문제