【发布时间】:2022-08-16 22:53:14
【问题描述】:
我正在努力解决与阻止通过同一线程(UI 线程)访问资源相关的问题。这是场景。用户单击屏幕上的对象。基于所选对象,绘制图(并将类的成员变量设置为所选对象)。通过该对象上的 CollectionChanged 事件接收对该选定对象位置的更新。该处理程序使用 Dispatcher.Invoke 编组到 UI 线程,在该线程中对绘图进行其他更新。在任何时候,用户都可以“取消选择”对象。发生这种情况时,所选项目的 class\' 成员变量设置为 null。问题是,可以随时接收更新。发生这种情况时,它会尝试访问现在为 null 的成员变量上的数据。我已经尝试过 Lock、mutex、semaphore、SemiphoreSlim,其 ctor 值为 1,1 等。但是似乎没有什么能阻止 UI 线程尝试访问集合更改事件的事件处理程序中的成员变量和用户选择事件处理程序(通过依赖对象值更改事件)同时访问成员变量。
DependencyObject 值更改事件处理程序(删除了无关代码):
try
{
mSemaphore.Wait();
if (mTrackHistory != null)
{
mTrackHistory.PositionData.CollectionChanged -=
PositionData_CollectionChanged;
}
mTrackHistory = e.NewValue as TrackHistoryInfo;
// If track history is null, don\'t do anything....
if (mTrackHistory != null)
{
Create initial plot
}
}
finally
{
mSemaphore.Release();
}
}
和 CollectionChanged 事件处理程序:
if (mDispatcher != Dispatcher.CurrentDispatcher)
{
mDispatcher.Invoke(() => PositionData_CollectionChanged(sender, e));
}
else
{
try
{
mSemaphore.Wait();
if (e.Action ==
System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
// Update the plot...
for (int idx = 0; idx < e.NewItems.Count; idx++)
{
(ECEF Position, DateTime Time) newInfo = ((ECEF Position, DateTime
Time))e.NewItems[idx];
// This is where it blows up attempting to access a null mTrackHistory
TimeSpan ts = newInfo.Time - mTrackHistory.StandupTime;
string stamp = $\"{ts.Hours:D2}:{ts.Minutes:D2}:{ts.Seconds:D2}\";
// Update plot with latest data
}
}
finally
{
mSemaphore.Release();
}
非常感谢任何有关如何防止此问题的建议/指导!
标签: c# multithreading reentrancy