我在Winforms应用程序中有以下代码,该代码是通过DataGridView
在BindingSource
中加载和显示数据的代码的一部分。
Imports System.Data.Entity
Imports System.Data.SqlClient
Imports System.Threading
Imports System.Threading.Tasks
Imports ForeNET.OrderMatching
Public Class frm_OrderMatching
Private m_Context As ForeContext
Private m_CurrentManufacturer As Byte = 0
Private m_CurrentSeries As String = ""
Private m_mreSeriesManfSet As ManualResetEvent
Private m_oc_tDSR As ObjectModel.ObservableCollection(Of tbl_Distribution_Stock_Restriction)
Private m_tLoadQryDistributionAllOrders As Task
Private m_tLoadSeriesManufacturer As Task
Private Sub LoadDistributionStockRestrictionTask()
Dim STime As DateTime = DateTime.Now, ETime As DateTime
If Not m_CTS.Token.IsCancellationRequested Then
DoDBContextAction(DBActivityType.Downloading, TimeSpan.FromSeconds(60), True, {False}, Sub() m_Context.tbl_Distribution_Stock_Restriction.Load())
Dim Tasks As List(Of Task) = New List(Of Task)
If m_tLoadQryDistributionAllOrders IsNot Nothing Then Tasks.Add(m_tLoadQryDistributionAllOrders)
If m_tLoadSeriesManufacturer IsNot Nothing Then Tasks.Add(m_tLoadSeriesManufacturer)
Task.WaitAll(Tasks.ToArray, m_CTS.Token)
DoDBContextAction(DBActivityType.Downloading, TimeSpan.FromSeconds(60), False, {True}, Sub() bs_tbl_Distribution_Stock_Restriction.ResetBindings(False))
m_mreSeriesManfSet.WaitOne(TimeSpan.FromSeconds(60))
If m_oc_tDSR IsNot Nothing Then RemoveHandler m_oc_tDSR.CollectionChanged, AddressOf m_oc_tDSR_CollectionChanged
'Debug.Print(m_Context.tbl_Distribution_Stock_Restriction.Local.ToString)
'Debug.Print(m_CurrentSeries)
'Debug.Print(m_CurrentManufacturer)
m_oc_tDSR = New ObjectModel.ObservableCollection(Of tbl_Distribution_Stock_Restriction)(From tDSR As tbl_Distribution_Stock_Restriction In m_Context.tbl_Distribution_Stock_Restriction.Local
Where (tDSR.AUS_SRS_CD = m_CurrentSeries And tDSR.ManufacturerID = m_CurrentManufacturer)
Select tDSR)
DoDBContextAction(DBActivityType.Downloading, TimeSpan.FromSeconds(60), False, {True}, Sub()
bs_tbl_Distribution_Stock_Restriction.DataSource = m_oc_tDSR
bs_tbl_Distribution_Stock_Restriction.ResetBindings(False)
End Sub)
AddHandler m_oc_tDSR.CollectionChanged, AddressOf m_oc_tDSR_CollectionChanged
End If
End Sub
Private Function DoDBContextAction(ActivityType As DBActivityType, Timeout As TimeSpan?, DoLock As Boolean, DoInvoke() As Boolean, ParamArray Action() As Action)
Dim Saved As Boolean = False, XLoadingBlocked As Boolean = False
If DoInvoke.Length <> Action.Length Then
Throw New ArgumentException("The number of elements in the DoInvoke() and Action() arrays must be the same.", "DoInvoke, Action")
End If
Do
If Not DoLock Then
For Ctr As Integer = 0 To Action.GetUpperBound(0)
If DoInvoke(Ctr) And Me.InvokeRequired Then
Me.Invoke(Action(Ctr))
Else
Action(Ctr)()
End If
Next
Saved = True
ElseIf Monitor.TryEnter(m_oDataContextLock, TimeSpan.FromMilliseconds(100)) Then
If XLoadingBlocked Then
' ...
XLoadingBlocked = False
' ...
End If
Try
For Ctr As Integer = 0 To Action.GetUpperBound(0)
If DoInvoke(Ctr) And Me.InvokeRequired Then
Me.Invoke(Action(Ctr))
Else
Action(Ctr)()
End If
Next
Saved = True
Catch ex As Exception
Throw
Finally
Monitor.Exit(m_oDataContextLock)
End Try
Else
If Not XLoadingBlocked Then
' ...
XLoadingBlocked = True
' ...
End If
Thread.Yield()
End If
Loop Until Saved Or (Timeout.HasValue AndAlso DateTime.Now - StartTime > Timeout.Value)
' ...
Return Saved
End Function
Private Sub frm_OrderMatching_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' Load Data...
m_Context = New ForeContext
With m_Context
.Database.Log = Sub(S As String) Debug.WriteLine(S)
.Configuration.LazyLoadingEnabled = False
Dim ConnStr As String = My.Settings.ConnectionString & ";multipleactiveresultsets=True;App=EntityFramework"
With .Database.Connection
If .ConnectionString <> ConnStr Or .State = ConnectionState.Closed Then
If .State <> ConnectionState.Closed Then
.Close()
End If
.ConnectionString = ConnStr
.Open()
End If
End With
End With
AddHandler DirectCast(m_Context, Infrastructure.IObjectContextAdapter).ObjectContext.SavingChanges, AddressOf ObjectContext_SavingChanges
m_CTS = New CancellationTokenSource
m_tsScheduler = New LimitedConcurrencyReprioritizableTaskScheduler(4)
m_lTaskList = New List(Of Task)
m_tLoadManufacturers = New Task(AddressOf LoadManufacturersTask, m_CTS.Token)
m_tLoadCrossBorder = New Task(AddressOf LoadCrossBorderTask, m_CTS.Token)
m_tLoadDistributionStockModyrsPermitted = New Task(AddressOf LoadDistributionStockModyrsPermittedTask, m_CTS.Token)
m_tLoadSeriesManufacturer = New Task(AddressOf LoadSeriesManufacturerTask, m_CTS.Token)
m_tLoadDistributionOrdersPermittedEvent = New Task(AddressOf LoadDistributionOrdersPermittedEventsTask, m_CTS.Token)
m_tLoadDistributionStockPermittedEvents = New task(AddressOf LoadDistributionStockPermittedEventsTask, m_CTS.Token)
m_tLoadLayers = New Task(AddressOf LoadLayersTask, m_CTS.Token)
m_tLoadDistributionSeriesManufacturersLayers = New Task(AddressOf LoadDistributionSeriesManufacturersLayersTask, m_CTS.Token)
m_tLoadDistributionOrdersRestriction = New Task(AddressOf LoadDistributionOrdersRestrictionTask, m_CTS.Token)
m_tLoadDistributionStockRestriction = New Task(AddressOf LoadDistributionStockRestrictionTask, m_CTS.Token)
m_tLoadFAWModel = New Task(AddressOf LoadFAWModelTask, m_CTS.Token)
m_tLoadPrimaryDealerGroup = New Task(AddressOf LoadPrimaryDealerGroupTask, m_CTS.Token)
m_tLoadModelCodes = New Task(AddressOf LoadModelCodesTask, m_CTS.Token)
m_tLoadMatchedOrdersTask = New Task(AddressOf LoadMatchedOrdersTask, m_CTS.Token)
m_tChangeDMOAFilterTask = Task.Factory.ContinueWhenAll({m_tLoadSeriesManufacturer, m_tLoadPrimaryDealerGroup}, AddressOf ChangeDMOAFilterTask, m_CTS.Token, TaskContinuationOptions.None, m_tsScheduler)
m_tChangeFMFilterTask = Task.Factory.ContinueWhenAll({m_tLoadSeriesManufacturer, m_tLoadFAWModel, m_tLoadModelCodes}, AddressOf ChangeFMFilterTask, m_CTS.Token, TaskContinuationOptions.None, m_tsScheduler)
m_lTaskList.AddRange({m_tLoadLayers, m_tLoadManufacturers, m_tLoadCrossBorder, m_tLoadSeriesManufacturer, m_tLoadDistributionOrdersPermittedEvent, m_tLoadDistributionStockPermittedEvents, m_tLoadFAWModel, m_tLoadDistributionStockModyrsPermitted, _
m_tLoadDistributionOrdersRestriction, m_tLoadDistributionStockRestriction, m_tLoadPrimaryDealerGroup, m_tLoadModelCodes, m_tLoadMatchedOrdersTask, m_tChangeFMFilterTask})
m_tLoadComplete = Task.Factory.ContinueWhenAll(m_lTaskList.ToArray, AddressOf LoadCompleteTask, m_CTS.Token, TaskContinuationOptions.None, m_tsScheduler)
m_tLoadManufacturers.Start(m_tsScheduler)
m_tLoadCrossBorder.Start(m_tsScheduler)
m_tLoadDistributionStockModyrsPermitted.Start(m_tsScheduler)
m_tLoadSeriesManufacturer.Start(m_tsScheduler)
m_tLoadDistributionOrdersPermittedEvent.Start(m_tsScheduler)
m_tLoadDistributionStockPermittedEvents.Start(m_tsScheduler)
m_tLoadLayers.Start(m_tsScheduler)
m_tLoadDistributionSeriesManufacturersLayers.Start(m_tsScheduler)
m_tLoadDistributionOrdersRestriction.Start(m_tsScheduler)
m_tLoadDistributionStockRestriction.Start(m_tsScheduler)
m_tLoadFAWModel.Start(m_tsScheduler)
m_tLoadPrimaryDealerGroup.Start(m_tsScheduler)
m_tLoadModelCodes.Start(m_tsScheduler)
m_tLoadMatchedOrdersTask.Start(m_tsScheduler)
End Sub
End Class
我间歇性地获得NullReferenceException
,“对象引用未设置为对象的实例。”位于LoadDistributionStockRestrictionTask
开头的m_oc_tDSR = New ObjectModel.ObservableCollection(Of tbl_Distribution_Stock_Restriction)(...
内。这个错误可能发生在十分之一的运行中,当调试时,如果我编辑,不做任何改动,然后再次运行,错误永远不会再发生。
堆栈跟踪是:
at System.Data.Entity.Core.Objects.ObjectStateManager.PerformAdd(IList`1 entries)
at System.Data.Entity.Core.Objects.ObjectStateManager.AlignChangesInRelationships(IList`1 entries)
at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges()
at System.Data.Entity.Core.Objects.ObjectContext.DetectChanges()
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
at System.Data.Entity.Internal.Linq.InternalSet`1.get_Local()
at System.Data.Entity.DbSet`1.get_Local()
at ForeNET.frm_OrderMatching.LoadDistributionStockRestrictionTask() in C:\Users\jzg48k\Documents\Visual Studio 2010\Projects\Fore GUI\Fore .NET\Forms\frm_OrderMatching.vb:line 1450
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
Task.WaitAll(Tasks.ToArray, m_CTS.Token)
中的行LoadDistributionStockRestrictionTask
可确保加载相关实体完成,m_Context.tbl_Distribution_Stock_Restriction.Local
,m_CurrentSeries
和m_CurrentManufacturer
具有有效值。相关行上方的Debug.Print行显示发生此错误时始终如此。
任何人都可以提出解决方案。