0

以下のコードは、Access2010データベースから一連のレコードを引き出します。したがって、自分のコネクタビットをローリングします。私はobservablecollectionを実行することに成功し、すべてを自分のオブジェクトからの優れたドラッグアンドドロップデータソースにバインドしました。しかし、気の利いた人のように、私はこれを非同期的に実行したいと思います。それでも、私は小さなキャストモンスターの問題を抱えています、そして私はそれを何に与えるべきかわかりません!誰かが私にアドバイスできますか?私はたくさんの本を読んでみましたが、金曜日の午後に一度に概念が少し多すぎて、実際に前進するのに苦労しています。

私が問題を抱えている行は次のとおりです。 Dim dispatcherObject As DispatcherObject = CType (handler.Target, DispatcherObject )

例外は次のとおりです。 Unable to cast object of type '_Closure$__2[SomeRecord_Viewer.SomeRecord]' to type 'System.Windows.Threading.DispatcherObject'.

以下のコードを使用してWPFリストボックスにデータを入力することができましたが、ObservableCollectionExクラスの一部をコメントアウトするだけです。これにより、同期の問題が発生し、数百のレコードが入力された後にクラッシュが発生します。

エンティティのスレッドリストを構築するクラス-この場合、ObservableCollectionEx(Of SomeRecord):

Class SomeRecordSet
Inherits ObservableCollectionEx( Of  SomeRecord)

Private Shared Property _SomeRecordList As New ObservableCollectionEx(Of  SomeRecord )
Public Shared ReadOnly Property SomeRecordList As ObservableCollectionEx(Of  SomeRecord )
    Get
        If _SomeRecordList.Count = 0 Then BuildSomeRecordListAsync()
        Return _SomeRecordList
    End Get
End Property

Public Shared ReadOnly Property ReturnSingleSomeRecord(id As Integer) As SomeRecord
    Get
        Return ( From SomeRecord In _SomeRecordList Where SomeRecord.id = id Select        SomeRecord).First()
    End Get
End Property

Private Shared Async Sub BuildSomeRecordListAsync()
    Await Task.Run( Sub() BuildSomeRecordList())
    Return
End Sub

Private Shared Sub BuildSomeRecordList()
    Db.newcmd( "Select * from  RecordList ")
    While Db.read
        Dim SomeRecord As New SomeRecord
        With SomeRecord
            .id = Db.dbint( "ID")
            .type = Db.dbin( "type")
         End With
        _SomeRecordList.Add(SomeRecord)
    End While
End Sub`

SomeRecordクラスの部分コード:

Class SomeRecord
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements                   INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged( ByVal info As String)
    RaiseEvent PropertyChanged(Me , New PropertyChangedEventArgs (info))
End Sub

...'lots of simple properties.
End Class

スレッド化されたコレクションのクラスコード-別のオンラインソースから翻訳されています。

'私はPostSharpを使ってキャッチを試します。`Public Class ObservableCollectionEx(Of T)Inherits ObservableCollection(Of T)'イベントをオーバーライドして、このクラスがアクセスできるようにしますPublic Shadows Event CollectionChanged As System.Collections.Specialized.NotifyCollectionChangedEventHandler

Protected Overrides Sub OnCollectionChanged( ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs )

    Using BlockReentrancy()

        Dim eventHandler As System.Collections.Specialized.NotifyCollectionChangedEventHandler = Sub () RaiseEvent CollectionChanged(Me , e)
        If (eventHandler Is Nothing) Then Return

        Dim delegates() As [Delegate] = eventHandler.GetInvocationList
*******If I comment this out I can populate the Listbox via a CollectionView, however it dies with issues to do with the list not staying synchronised :).
        'Walk thru invocation list 
        For Each handler As System.Collections.Specialized.NotifyCollectionChangedEventHandler     In delegates
            Dim dispatcherObject As DispatcherObject = CType (handler.Target, DispatcherObject)
            ' If the subscriber is a DispatcherObject and different thread
            If (( Not (dispatcherObject) Is Nothing) AndAlso (dispatcherObject.CheckAccess = False )) Then
                ' Invoke handler in the target dispatcher's thread
                dispatcherObject.Dispatcher.Invoke(DispatcherPriority .DataBind, handler, Me, e)
            Else
                handler( Me, e)
            End If
        Next

*******End of stuff I comment out to get working partially***

    End Using
End Sub
End Class
4

2 に答える 2

1

私が見ることができることから、あなたは2つの問題を抱えています。

  1. eventHandler実際のイベントハンドラーではなく、匿名メソッドにローカル変数を割り当てています。そのはず:

    Dim eventHandler As NotifyCollectionChangedEventHandler = CollectionChangedEvent
    

    注意:CollectionChangedEventではなく、VBで使用する必要がありますCollectionChanged

  2. CTypeを使用してターゲットをにキャストします。DispatcherObjectこれは、ターゲットが。でない場合は機能しませんDispatcherObjectTryCast代わりに使用してください:

    Dim dispatcherObject As DispatcherObject = TryCast(handler.Target, DispatcherObject)
    

次の行で、次を使用してテストを整理することもできますIsNot

If dispatcherObject IsNot Nothing AndAlso Not dispatcherObject.CheckAccess Then
于 2013-01-11T19:41:14.730 に答える
0

警告-以下のコードは、C#バージョンとは動作が異なります。主な違いは、VBではイベントをオーバーライドできないことです(なぜ地球上ではオーバーライドできないのですか?)が、C#ではオーバーライドできます。

その結果、ハンドラーはVBではNothingですが、C#ではありません:(。

したがって、構文はエラーなしでビルドされますが、VBバージョンは何も実行しません。

VBで更新された回答でやり直します。ありがとうございました!

まだEntityFrameworkでこれを機能させることはできません。しかし、コレクションではなく、私とEFの問題だと思います。

コード自体は興味のある人のためにここにあります。私のリストは今では完全にうまく入力されています。しかし、私がどのように広範囲にテストしたかを更新するまで、私は塩の小さなピンチで私のこの答えをおそらく取るでしょう:)

ただし、前兆は良好です。元のC#作成者のサイトは次のとおりです。元のサイト

Public Class ObservableCollectionEx(Of T)
Inherits ObservableCollection(Of T)



'Override the event so this class can access it
Public Shadows Event CollectionChanged As NotifyCollectionChangedEventHandler

Protected Overrides Sub OnCollectionChanged(ByVal e As NotifyCollectionChangedEventArgs)
    Using BlockReentrancy()
        Dim eventHandler As System.Collections.Specialized.NotifyCollectionChangedEventHandler = CollectionChangedEvent
        If eventHandler Is Nothing Then
            Return
        End If


        Dim delegates() As [Delegate] = CollectionChangedEvent.GetInvocationList
        'Walk thru invocation list
        For Each handler As NotifyCollectionChangedEventHandler In delegates
            Dim dispatcherObject As DispatcherObject = TryCast(handler.Target, DispatcherObject)
            ' If the subscriber is a DispatcherObject and different thread
            If dispatcherObject IsNot Nothing AndAlso Not dispatcherObject.CheckAccess Then
                ' Invoke handler in the target dispatcher's thread
                dispatcherObject.Dispatcher.Invoke(DispatcherPriority.DataBind, handler, Me, e)
            Else
                handler(Me, e)
            End If
        Next
    End Using
End Sub

エンドクラス

于 2013-01-12T20:40:25.753 に答える