我有一个使用 MVVM 设计模式和异步数据访问方法的大型 WPF 应用程序。它使用带有回调处理程序和接口的旧式异步代码IAsyncResult
......这是一个典型的例子:
function.BeginInvoke(callBackMethod, asyncState);
然后,在视图模型中,我有以下回调处理程序:
private void GotData(GetDataOperationResult<Genres> result)
{
UiThreadManager.RunOnUiThread((Action)delegate
{
if (result.IsSuccess) DoSomething(result.ReturnValue);
else FeedbackManager.Add(result);
});
}
RunOnUiThread
方法基本如下:
public object RunOnUiThread(Delegate method)
{
return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
此问题仅影响一种视图模型,即允许用户编辑Release
对象的视图模型。在相关视图上,填充 es 的某些集合ComboBox
在首次加载时会从数据库中请求。让我们简化这个说法,即只有一个名为 的集合Genres
。数据到达视图模型后,处理如下:
private void GotGenres(GetDataOperationResult<Genres> result)
{
UiThreadManager.RunOnUiThread((Action)delegate
{
if (result.IsSuccess) Genres.AddEmptyItemBefore(result.ReturnValue);
else FeedbackManager.Add(result);
});
}
当集合存在并且Release
在 UI 中选择了一个对象时,我有以下代码Release.Genre
从集合中选择当前值:
if (!Release.Genre.IsEmpty && Genres.ContainsItemWithId(Release.Genre.Id))
Release.Genre = Genres.GetItemWithId(Release.Genre);
在这一点上,我应该注意到这一切都很好,这是唯一Release.Genre
从视图模型中引用属性的行。
我的特殊问题是,有时该Release.Genre
属性设置为null
,我无法弄清楚如何或从哪里开始。>> 编辑 >> 当我在属性设置器上放置一个断点时,<< 编辑 <<Call Stack
没有提供关于设置null
值的真正线索,因为只有[Native to Managed Transition]
一行。从窗口中选择Show External Code
选项后Call Stack
,我可以看到基本的异步代码调用:
现在,我可以确认在尝试解决此问题时发现的以下事实:
Release.Genre
引用该属性的一行未将其设置为null
.- 对 Genres.AddEmptyItemBefore(result.ReturnValue) 的调用未将其设置为
null
... 这只是Genres
在添加 'empty' 后将结果集合添加到集合中Genre
。 - 该
Release.Genre
属性有时被设置为null
在调用 Genres.AddEmptyItemBefore(result.ReturnValue) 时或之后,但不是因为它......在几次单步执行时,执行已经跳到(以不相关的方式)到中断我在输入参数Release.Genre
所在的属性设置器上设置的点,但这并不是每次都发生。value
null
- 它通常发生在从相关视图模型到
Release
视图模型时,但不是每次都发生。 - 相关视图模型没有对该
Release.Genre
属性的引用。
需要明确的是,我并不是要求任何人从我提供的稀疏信息中调试我的问题。我也没有就进行异步数据调用征求意见。相反,我真的在努力寻找我还没有想到的新方法。我知道某处的某些代码(几乎可以肯定是我的代码)将属性设置为null
...我的问题是如何检测此代码的位置?它似乎不在Release
视图模型中。在没有更多线索的情况下,如何继续调试此问题?