2009-08-25 4 views
2

사이트를 둘러 보았습니다.이 주제와 관련하여 찾은 질문은 C# (유지 관리중인 응용 프로그램은 VB.NET으로 작성되었습니다)이므로 간과하면 사과드립니다. 하나. 내 스레드 호출하고 여기 어디에크로스 스레드 작업이 유효하지 않습니다. VB.NET

는 : 여기

Private Sub saveBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles saveBtn.Click 
    If Not LoadedFilePath = String.Empty Then 
     Dim oTrd = New Threading.Thread(AddressOf SaveData) 
     oTrd.Start() 
    End If 
End Sub 

그리고하는 방법은 다음과 같습니다

Private Sub SaveData() 
    SaveData(LoadedFilePath) 
End Sub 
Private Sub SaveData(ByVal filepath As String) 
    If InvokeRequired Then 
     Me.Invoke(New MethodInvoker(AddressOf SaveData)) 
    End If 
    Try 
     Me.Cursor = Cursors.WaitCursor 
     Dim oSettings As New SettingsClass(filepath) 
     Dim oEnc As New AES 
     With oSettings 
      //' Code removed for brevity 
     End With 
     oEnc = Nothing 
     oSettings.SaveSettings() 
     savedLbl.Visible = True 
     If SavedTimeout IsNot Nothing Then 
      Try 
       SavedTimeout.StopEvent() 
      Catch 
      End Try 
     End If 
     SavedTimeout = New TimedEvent(Now.AddSeconds(5)) 
     SavedTimeout.StartEvent() 
     Me.Cursor = Cursors.Default 
    Catch ex As Exception 
     MsgBox(ex.Message) 
    End Try 
End Sub 

, 저장 기능이 잘 작동,하지만 난 크로스 스레드 중 오류를 얻을 수 프로그램은 커서를 기본값으로 다시 전환하려고 시도합니다. 이 문제를 해결하려면 어떻게해야합니까?

답변

5

소유자 (GUI) 스레드에서 메소드를 호출하는 방법이 잘못되었습니다. 호출이 필요한 경우 메소드에서 나머지 코드를 실행하지 않아야합니다. 그렇게하면 GUI 스레드와 백그라운드 스레드 모두에서이를 실행하게되고 백그라운드 스레드에서 GUI 요소에 액세스하려고하면 크로스 스레드 오류가 발생합니다.

Private Sub SaveData(ByVal filepath As String) 
    If InvokeRequired Then 
     Me.Invoke(New MethodInvoker(AddressOf SaveData)) 
    Else 
     ... the actual code 
    End If 
End Sub 

을하지만 어쨌든 GUI 스레드에서 자신을 호출해야 할 때 당신은 왜, 백그라운드 스레드에서 방법을 시작 :

호출이나는 다음과 같이해야합니까?

+0

와우 하하 내가 다른 것을 잊어 버렸다고 믿을 수 없다 ... FTL! 해결책을 가져 주셔서 감사합니다 :) – Anders

+0

@ 앤더스 : 개인적으로 저는'Else'없이 그것을 남기고,'Me.Invoke()'바로 다음에'Return'을 추가하여 더 이상 실행되지 않게합니다. 중첩을 줄임으로써 코드를 읽기 쉽게 유지하는 데 도움이됩니다. – STW

+0

@yoooder : 팁 주셔서 감사 드리며이를 명심하십시오. – Anders

1

사용자 인터페이스를 호출 할 수없는 도우미 스레드를 시작했습니다. UI 쓰레드에서만 커서를 설정할 수 있습니다.

이 작업을 수행하려면 도우프 스레드에서 UI 스레드에 작업이 완료되었음을 알리는 이벤트를 발생시켜 커서를 다시 설정하거나 UI 스레드로 호출하여 수행하십시오.

private void ResetCursor() 
{ 
    this.Cursor = Cursor.Default; 
} 

private delegate void UpdateCursor(); 
private void SaveData() 
{ 
    //Do your work here 
    if(this.InvokeRequired) 
    { 
     this.Invoke(new UpdateCursor(ResetCursor)); 
    } 
    else 
    { 
     ResetCursor(); 
    } 
} 
0

다중 스레드 Windows Forms 응용 프로그램에서 스레드를 만든 스레드가 아닌 다른 스레드에서 컨트롤의 메서드 나 속성을 호출하는 것은 불법입니다. 모든 크로스 스레드 호출은 Control.Invoke 또는 Control.BeginInvoke 메서드를 사용하여 컨트롤 (일반적으로 주 스레드)을 만든 스레드에 명시 적으로 마샬링되어야합니다. 여기

는이 문제를 해결하는 데 도움이하는 데 사용할 수있는 웹 페이지입니다 :

http://www.dreamincode.net/forums/showtopic35616.htm C#을

http://www.codeproject.com/KB/vb/ISinchronizedInvoke.aspx이 웹 페이지가 제거 다운 코드에 액세스하는 데 필요한있다

관련 문제