今天早些时候,我正在寻找一个非常奇怪的错误...我最终将其追溯到似乎导致问题的原因。
原始报告可以在这里找到:original question
细节已经改变,足以保证一个新问题。
看起来我的应用程序有时候,并非所有时间,当它达到以下LINQ查询时冻结:
using (NetworkDatabaseContext db = new
NetworkDatabaseContext(UISession.ConnectionString))
{
Ballast ballast = db.Ballasts.FirstOrDefault(b => b.NetworkId == UISession.NetworkId &&
b.ShortAddress == this.innerBallast.ShortAddress && b.ControllerSerial == this.controllerSerial);
这就是它的样子:
大部分时间这个工作都很好......但是时不时会锁定。此代码是BallastListItem类的一部分。此类的项目绑定到页面上的ListBox:
<ListView Name="lstBallasts" Margin="5" DockPanel.Dock="Top" MinHeight="100"><!-- The MinHeight is used to get a good view in the designer -->
<ListView.View>
<GridView>
<GridViewColumn Header="Address" DisplayMemberBinding="{Binding InnerBallast.ShortAddress}" Width="70"/>
<GridViewColumn Header="Name" Width="300">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="txtBallastDisplayName" Text="{Binding DisplayName}" Width="270" MaxWidth="270" MaxLength="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Type" DisplayMemberBinding="{Binding DeviceType}" Width="150"/>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding InnerBallast.StandardVersion}" Width="150"/>
</GridView>
</ListView.View>
</ListView>
该代码是DisplayName属性getter的一部分:
public string DisplayName
{
get
{
using (NetworkDatabaseContext db = new NetworkDatabaseContext(UISession.ConnectionString))
{
Ballast ballast = db.Ballasts.FirstOrDefault(b => b.NetworkId == UISession.NetworkId &&
b.ShortAddress == this.innerBallast.ShortAddress && b.ControllerSerial == this.controllerSerial);
所以这个代码在数据绑定发生时被调用,之前应该已经意识到了。我仍然不知道为什么这有时会导致问题......
UPDATE
在这两种情况下(当应用程序冻结时,如果没有),连接状态在查询代码之前就是“已关闭”,我可以从以下方面看到:
db.Connection.State.ToString()
更新2我忘了提到我将该代码移出getter,所以它只获取一次。第一次执行此操作时一定是在睡觉。代码工作正常,虽然在XP上......时不时,但问题仍然少发生。
*更新3 *为了清楚起见,我使用的SQL Compact数据库数据非常少
让属性打开数据库连接并运行查询不是一个好的模式。
更好的方法是从LINQ到SQL查询一组对象,并将它们绑定到WPF控件。
我同意Damien,为什么不异步执行DB调用?这样UI就能保持响应,你可以优雅地处理背景中的DB错误,而无需用户知道......