2010-02-20 3 views
3

는 내가 쓰고 프로그램을 테스트하고 있었고, 난이 오류 메시지를 받았습니다 : Cross-thread operation not valid: Control 'lblStatus' accessed from a thread other than the thread it was created on.NET에서 크로스 스레드 예외를 디버그하는 방법은 무엇입니까?

코드는 조금 대규모 내가 작은 세그먼트를 게시하려면이 오류의 원인이되는 부분을 모르겠습니다. 그러나 여기에 사용할 수있는 정보가 있습니다.

명시 적으로 "스레딩"을 사용하지 않습니다. 다른 것들이 자동으로 여러 스레드를 만들고있는 것 같아요 - Wii 원격 하드웨어 액세스 라이브러리를 사용하고 그래픽 조작을하고 있습니다.

스택 추적은 lblStatus이 수정하려고 시도했지만 실패한 함수를 호출하는 변경 이벤트 핸들러를 호출 함을 나타냅니다.

이 오류 유형을 어떻게 디버깅합니까? 난 비주얼 스튜디오에게 내가 명확히하고자 2008 년

편집

한 가지를 사용하고,이 다른 스레드도 와서 방법을 모르겠어요. 어떻게 내가 이걸 찾을 수 있을까? 다른 thread의 소스

+0

Visual Studio 2008 디버거에 연결하지 않아도 정보를 제공합니까? –

+0

@Moron : 디버거가 정보를 보여 주지만 변수를 감시하고 스택을 호출하지만 스레드에 대한 정보가 표시되는지 잘 모르겠습니다. 만약 그렇다면, 나는 어디 있는지 모른다. 누군가가하는 경우 알려주세요. – Aishwar

+1

디버그 -> 창 -> 스레드. –

답변

4
public void SetStatus(string msg) 
{ 
    if (lblStatus.InvokeRequired) 
     lblStatus.Invoke(new MethodInvoker(delegate 
     { 
      lblStatus.Text = msg; 
     })); 
    else 
     lblStatus.Text = msg; 
} 

이렇게하면 레이블 텍스트가 업데이트됩니다. BeginInvoke를 들어

이 내가 아는 방법 (좀 더 우아한 구현이 알고) -하지만 난 아직 멀티 스레드 응용 프로그램이 시도하지 않은 : 다른 방법에 대한

Action<string> setStatus= target.AppendText; 

void OnSomeEvent (object sender, EventArgs e) 
{ 
    IAsyncRes iares = setStatus.BeginInvoke("status message", null, null); 
    setStatus.EndInvoke(iares); 
} 

public void SetStatus(string msg) 
{ lblStatus.Text = msg; } 

SnOrfus는 제어 스레드와 동기화되는 훌륭한 링크를 참조합니다. BeginInvoke 위의 내 예제는 이 아니며이 아니며 컨트롤의 스레드와 동기화됩니다.

지금까지 스레드의 원인이 무엇으로 : 나는 명확히 할 About WiimoteChanged event

+1

+1 : 또는 UI 스레드에서 차단하지 않으려면 BeginInvoke를 사용하십시오. –

+0

@ SnOrfus : 끝나면 EndInvoke를 호출 할 의사가있는 경우에만. –

+0

@ dboarman : WiimoteChanged 이벤트에 대한 링크를 제공해 주셔서 감사합니다. 나는 이것을 조금 더 편하게 느낀다. – Aishwar

2

주 스레드가 아닌 다른 스레드에서 시각적 요소에 액세스 할 수 없습니다. 시각적 요소를 업데이트하는 대리자를 호출하려면 Dispatcher.Invoke()을 사용해야합니다.

예 :

this.Dispatcher.Invoke((Action)(() => lblStatus.Content = "Hello")); 

또는 (람다없이) :

당신은 당신의 스레드 대표의 사용을 결합해야
this.Dispatcher.Invoke((Action)delegate() { lblStatus.Content = "Hello"; }); 
+0

@ 제이크 : 답변 주셔서 감사합니다. WPF를 사용하지 않고 winforms를 사용해야합니다. – Aishwar

0

..

이 대리자로 방법을 지정하고 스레드를 통해 대리자를 호출합니다.

0

한 가지, 내가 모르는를 앱이 멀티 스레드되지 않으면이 다른 스레드도

을 온 방법 이 문제는 Visual Studio 호스팅 프로세스로 인해 발생할 수 있습니다. Visual Studio 호스팅 프로세스는 주 스레드를 시작한 다음 응용 프로그램이 실행되는 새 UI 스레드를 만듭니다. 경우에 따라 스레드 간 예외 (예 : when accessing Form.ActiveForm before calling Application.Run)가 발생할 수 있습니다.

문제가 발생한 경우 프로젝트 속성의 디버그 탭에서 "Visual Studio 호스팅 프로세스 사용"을 선택 취소 할 수 있습니다.

관련 문제