2012-03-19 5 views
2

카드 게임이 될 VB 실버 라이트 앱이 있습니다. 나는 개인 카드 (Silverlight "Image"컨트롤로 자신의 "CardImage"클래스로 래핑 된 프로그래밍 방식으로 생성)를 가져 와서 마우스를 움직일 때 이동하려고했습니다. 마우스를 올리면 팝업이 나타나기를 원하고 마우스가 떠날 때 다시 내려주세요.Silverlight에서 크로스 스레드 예외가 잘못되었습니다.

본질적으로 Image.Margin.Top을 마우스 포인트에서 5 픽셀 위로 이동하고 mouseleave 이벤트에서 5 픽셀 아래로 이동했습니다.

잘못된 크로스 스레드 액세스와 관련하여 두려운 "처리되지 않은 예외"가 발생하여 숙제를 마쳤으며 UI 스레드와 작업자 스레드 등을 배웠고 전체 "begininvoke "더 안전한 스레드가되도록 연습하는 것.

다음과 같은 문제가 있습니다. 예외가 여전히 발생합니다.

여기 내 코드입니다 :

Public Class CardImage 

Public Disp As Dispatcher = Deployment.Current.Dispatcher 
Public WithEvents Image As New Image 

Private Sub MouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Image.MouseEnter 
    Try 
     Invoke(Sub() Image.Margin = New Thickness(Image.Margin.Left, Image.Margin.Top - 5, 0, 0)) 
    Catch ex As Exception 

    End Try 
End Sub 
Private Sub MouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Image.MouseLeave 
    Try 
     Invoke(Sub() Image.Margin = New Thickness(Image.Margin.Left, Image.Margin.Top + 5, 0, 0)) 
    Catch ex As Exception 

    End Try 
End Sub 

Private Sub Invoke(ByVal act As Action) 
    If Disp.CheckAccess Then 
     act.Invoke() 
    Else 
     Disp.BeginInvoke(act) 
    End If 
End Sub 
End Class 

내가 (에서 13 개 카드의 "손"으로) 표시되는 모든 카드를 통해 매우 빠르게 마우스를 이동하면 예외가 발생합니다. 플레이어가 이런 종류의 일을 끝낼 수도 있다는 사실을 명심하십시오. ADHD를 가진 일부 사용자가 카드가 파문을 일으키고 "물결을 반복"하기를 원하기 때문에 앱이 충돌하는 것을 원치 않습니다. 다른 사람들이 카드를 사용하기를 참을성있게 기다리는 동안.

내 UI 스레드가 여전히 이미지 여백을 업데이트하는 스레드를 사용하지 않는 이유에 대한 힌트가 있습니까?

+0

: 나는 –

+0

좋아, 내 대답은 틀렸어. 당신의 메소드가 이벤트 핸들러에서 왔기 때문에, 나는 이미 UI 스레드에 있다고 생각할 것이다. 다른 스레드에서 CardImage 인스턴스를 프로그래밍 방식으로 생성하고 있습니까? – Kratz

+0

@Kratz 카드 이미지는 기본 Silverlight 페이지에서 버튼 클릭 이벤트 발생의 결과로 생성됩니다. 버튼 (단순히 새로운 테스트 핸드를 "처리"하는 버튼)은 CardImage 객체 52 개를 모두 만들고 정렬합니다. 따라서 UI 스레드에 모두 포함될 것이라고 생각할 수 있습니다. –

답변

0

'이미지'는 CardImage를 생성하는 스레드의 컨텍스트에서 만들어집니다. . 즉, UI 스레드 아니지만 작업자 스레드를 사용하면 마우스 이벤트를 파견 곳으로합니다 (UI 스레드에서 액세스 할 수없는 경우

을 UI 스레드에서 만들기 : 참고

Public WithEvents Image As Image 

Public Sub New() 

    Image = Invoke(Function() 
         return New Image 
        End Function) 

End Sub 

Private Function Invoke(ByVal procedure As Func(of System.Windows.Controls)) 

    If Disp.CheckAccess Then 
     return procedure.Invoke() 
    Else 
     return Disp.Invoke(procedure) 
    End If 

End Function 
관련 문제