2009-08-01 4 views
1

현재 이해가 안가는 이상한 문제가 있습니다. 하나의 단추가 & 하나의 richeditbox 인 간단한 GUI가 있습니다. 비동기 소켓이 실행 중이며 네트워크를 통해 gui (richeditbox)로 인쇄하려는 일부 데이터를 수신하고 있습니다. 비동기 소켓은 사용자가 버튼을 눌렀을 때 시작됩니다. 내가 네트워크 데이터를받을 때 그래서 나는 (를 Form1 클래스)처럼 보이는 여기 방법, 데이터를 출력하는 함수를 호출 :비동기 소켓이있는 Windows Forms; 텍스트 출력 없음

Public Sub AddText(ByVal text As String) 

Try 

    Console.WriteLine(text) 
    RichTextBox1.AppendText(text) 
    RichTextBox1.AppendText(vbNewLine) 

Catch e As Exception 
    Console.WriteLine(e.ToString()) 
End Try 

End Sub 

그럼 난 단순히 내 네트워크 클래스 또는 모듈 (그것은 중요하지 않습니다에서 Form1.AddText(..)을 ?). 문제는 AddText 함수가 호출되고 있지만 예외가없고 오류가없고 아무것도 없다고해도 richeditbox에 아무것도 표시되지 않는다는 것입니다. 디버거를 통해 보았습니다. "text"에는 인쇄해야하는 데이터가 포함되어 있지만 단순히 아무 것도 나타나지 않습니다. 누구나 아이디어가 있습니까?

답변

1

소켓이 다른 스레드 (물론 비동기이기 때문에)에서 실행중인 경우 RichTextBox에 텍스트를 표시하려면 InvokeRequired을 사용해야 할 수 있습니다. 비동기 시리얼 포트 리스너에서 리스너와 비슷한 문제가 발생했습니다.

+0

나는 이미 그것을 시도했지만 같은 결과했습니다/ 는 개인 위임 하위 dlgUpdate (문자열로 ByVal의 텍스트) 는 하위 updateLog (문자열로 ByVal의 텍스트) 만약 진정한 RichTextBox1.InvokeRequired = 그런 다음 희미한 D로 새로운 dlgUpdate (AddressOf를 updateLog) RichTextBox1.Invoke (D, 텍스트) 그렇지 RichTextBox1.AppendText (텍스트) 최종면 끝 하위 참고 : 나는 GUI 스레드에서 호출 할 경우 updateLog 기능이 작동, 그래서 그것을 추측 그 관련이 있지만 InvokeRequired 사용 후 여전히 작동하지 않는 이유를 볼 수 없습니다. –

+0

어 .. 그 못 생겼어, 심지어 코드에서 주석을 볼 수 없다, 나는 코드를 가져 갔다 : http://www.vbdotnetforums.com/asp-net-data-access/19740-how-use-invokerequired .html –

+0

이것은 암시적인 제안 일 수 있지만 UI 스레드가 잠겨 있으면 텍스트를 추가 한 후에 Application.DoEvents()를 던져 볼 수 있습니다. – David

1

David는 맞습니다. 여기에 예제가 있습니다.

Delegate Sub AddTextDelegate(ByVal text as String) 

Public Sub AddText(ByVal text as String) 
    If Me.InvokeRequired Then 
     Me.Invoke(new AddTextDelegate(AddressOf Me.AddText), new object() { text }) 
    Else 
     Try 
      Console.WriteLine(text) 
      RichTextBox1.AppendText(text) 
      RichTextBox1.AppendText(vbNewLine) 
     Catch e as Exception 
      Console.WriteLine(e.ToString()) 
     End Try 
    End If 
End Sub 

거래가 생성 된 스레드에서 컨트롤을 업데이트해야한다는 점이 다릅니다. AddText() 루틴이 비동기 소켓 스레드의 컨텍스트에서 호출되는 것처럼 들립니다. AddText() 루틴은 재귀 함수처럼 동작합니다. 처음 호출 될 때 InvokeRequired 속성이 true가됩니다. 이렇게하면 데이터를 올바른 스레드로 마샬링하는 Invoke() 호출을 통해 다시 호출하게됩니다. 두 번 호출하면 InvokeRequired가 false가되고 컨트롤이 업데이트됩니다.

+0

감사합니다. 그래도 여전히 작동하지 않습니다. 나는 디버거를 검사했고 매번 InvokeRequired라는 함수가 "false"였습니다. 그리고 그것은 참으로, 관련이 있습니다. 왜냐하면 디버깅 할 때 addText 함수가 "MainThread"에서 호출되지 않기 때문입니다. 당신의 도움을 주셔서 감사합니다! –

+0

필자는 AddText 함수가 MainThread (예 : Form1_Load)에서 호출 될 때만 작동한다는 것을 의미했습니다. –

0

수정 됨. 그것은 형식이기 때문에 Form1을 사용하여 함수를 호출 할 수 없었습니다. diff 스레드 이후 자체 메모리가있는 새로운 var과 같습니다. 그래서 InvokeRequired를 체크했을 때 폼이 보이지 않았기 때문에 폼 1이 그 쓰레드에 속해서 텍스트가 표시되지 않았기 때문에 false라고 말했습니다. 따라서 Public myForm As Form1과 같은 전역 변수를 만들고 Form1_Load에서 myForm을 Form1에 할당했습니다.