C# 如何调试具有异步数据访问和无调用堆栈的WPF应用程序?
我有一个使用MVVM设计模式和异步数据访问方法的大型WPF应用程序。它使用带有回调处理程序的旧式异步代码和C# 如何调试具有异步数据访问和无调用堆栈的WPF应用程序?,c#,wpf,debugging,asynchronous,data-access,C#,Wpf,Debugging,Asynchronous,Data Access,我有一个使用MVVM设计模式和异步数据访问方法的大型WPF应用程序。它使用带有回调处理程序的旧式异步代码和IAsyncResult接口。。。下面是一个典型的例子: function.BeginInvoke(callBackMethod, asyncState); 然后,在视图模型中,我有以下回调处理程序: private void GotData(GetDataOperationResult<Genres> result) { UiThreadManager.RunOnUi
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);
});
}
此问题只影响一个视图模型,该模型允许用户编辑发布
对象。在相关视图中,首次加载数据库时,会从数据库中请求填充组合框的某些集合。让我们简化一下,这里只有一个集合叫做Genres
。数据到达视图模型后,将按如下方式处理:
private void GotGenres(GetDataOperationResult<Genres> result)
{
UiThreadManager.RunOnUiThread((Action)delegate
{
if (result.IsSuccess) Genres.AddEmptyItemBefore(result.ReturnValue);
else FeedbackManager.Add(result);
});
}
在这一点上,我应该注意到这一切都很好,并且这是从视图模型中引用Release.Genre
属性的唯一一行
我特别的问题是,有时
Release.Genre
属性设置为null
,我无法确定如何或从何处开始。>>编辑>>当我在属性设置器上设置断点时,我通常使用平面文件、XML或数据库日志进行调试。我创建这些日志类是为了记录日志,所以我可以从我开发的每个应用程序中调用它
对于数据库日志记录,您可以简单地执行以下操作:
void WriteLog(string log){
// Your database insert here
}
也许您需要datetime和其他支持信息,但这取决于开发人员。对于简单的平面文件日志记录:
void WriteLog(string log){
using(TextWriter tx = new StreamWriter("./Log/" + DateTime.Now.ToString() + ".txt", false)){
tx.WriteLine(log);
}
}
您可以通过两种方式在应用程序中使用日志记录:
1:方法调用
WriteLog((Release.Genre == null).ToString());
if (!Release.Genre.IsEmpty && Genres.ContainsItemWithId(Release.Genre.Id))
Release.Genre = Genres.GetItemWithId(Release.Genre);
2:将其添加到发布中。流派集(或get)属性
有了它,您可以尝试获取调用序列,无论在调用之前、调用期间等其他地方是否设置了Release.Genre
请注意,我只是给出了建筑日志的一般图像。请期待错误。但是,开发人员有责任开发日志记录功能以满足要求。平面文件日志记录或数据库日志记录是否可以帮助您?如果无法使用VS进行调试,通常我会使用这两个日志记录,尤其是在WPF中,因为绑定不太可能是可调试的。我认为这不是由任何代码引起的。您必须在某个地方绑定到该属性,该属性应更改为
OneWay
@Fendy,请您进一步解释您的想法好吗@HighCore,我当时以为你找到了什么,因为我的绑定到组合框上的流派的集合没有OneWay=True
。不幸的是,在我添加它之后,我仍然有完全相同的问题。@Sheridan在下面看到我的答案除了尝试单步检查代码外,您是否可以在发布.Genre
setter上设置一个条件断点,以确定value==null
的时间?然后检查调用堆栈或从那里找到罪犯?感谢您扩展您的想法@Fendy。虽然很有趣,但我不确定这对我在这种情况下有什么帮助。据我所知,此方法无法帮助我发现是什么将属性设置为null
。事实上,如果我错了,请纠正我,但这似乎比在二传手上设置一个断点更有帮助。@Sheridan它不像断点那么容易,但这种方法可以完成这项工作。您可以记录DateTime和其他信息,如方法名或变量,以代替断点。在可能放置断点的位置进行日志记录。
void WriteLog(string log){
using(TextWriter tx = new StreamWriter("./Log/" + DateTime.Now.ToString() + ".txt", false)){
tx.WriteLine(log);
}
}
WriteLog((Release.Genre == null).ToString());
if (!Release.Genre.IsEmpty && Genres.ContainsItemWithId(Release.Genre.Id))
Release.Genre = Genres.GetItemWithId(Release.Genre);
public class Release{
private Genre _genre=null;
public Genre Genre{
get{
WriteLog((_genre == null).ToString());
return _genre;
}
set{
WriteLog((_genre == null).ToString());
_genre = value;
}
}
}