以下のコードは、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