我在加载页面时从SQLite
数据库加载一个列表,有时加载时我会NullReferenceException
收到错误Object reference not set to an instance of an object.
它破坏了SQLite类文件中的代码
public TableMapping GetMapping (Type type)
{
if (_mappings == null) {
_mappings = new Dictionary<string, TableMapping> ();
}
TableMapping map;
if (!_mappings.TryGetValue (type.FullName, out map)) {
map = new TableMapping (type);
_mappings [type.FullName] = map; //null here
}
return map;
}
这是我加载页面时的操作
public MainPage()
{
this.InitializeComponent();
Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
createDatabase();
getBowlers();
}
private async void createDatabase()
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection(BOWLERS_DATABASE);
await conn.CreateTableAsync<Bowler>();
conn = new SQLiteAsyncConnection(GAMES_DATABASE);
await conn.CreateTableAsync<Games>();
}
private async void getBowlers()
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection(BOWLERS_DATABASE);
var query = conn.Table<Bowler>();
itemListView.DataContext = await query.ToListAsync();
}
我是页面生命周期的新手,但似乎我试图从数据库中提取到可能的早期?
修改
栈跟踪
System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=mscorlib
StackTrace:
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
at SQLite.SQLiteConnection.GetMapping(Type type) in c:\Users\Jeff\Dropbox\Tournament Director Windows\Tournament Director Windows\SQLite.cs:line 231
at SQLite.TableQuery`1..ctor(SQLiteConnection conn) in c:\Users\Jeff\Dropbox\Tournament Director Windows\Tournament Director Windows\SQLite.cs:line 2129
at SQLite.SQLiteConnection.Table[T]() in c:\Users\Jeff\Dropbox\Tournament Director Windows\Tournament Director Windows\SQLite.cs:line 616
at SQLite.SQLiteAsyncConnection.Table[T]() in c:\Users\Jeff\Dropbox\Tournament Director Windows\Tournament Director Windows\SQLiteAsync.cs:line 260
at Tournament_Director_Windows.MainPage.<getBowlers>d__c.MoveNext() in c:\Users\Jeff\Dropbox\Tournament Director Windows\Tournament Director Windows\MainPage.xaml.cs:line 116
InnerException:
答案 0 :(得分:4)
基于异常并提供了堆栈跟踪,我认为您的问题是here所描述的内容。
注意:
Dictionary不是线程安全的。这意味着如果它被多个线程访问,则应该同步对它的访问。
更新1
在SQLite异步处理中似乎是there is a bug。
答案 1 :(得分:1)
原始代码的问题是GetMapping方法不是线程安全的。在下面添加一个锁,强制它是线程安全的并解决问题。
根据答案和评论,这里是代码,将SQLite.cs文件中的GetMapping方法更改为
private Object thisLock = new Object(); // add lock obj
public TableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None)
{
// include original code in the lock block
lock (thisLock)
{
if (_mappings == null)
{
_mappings = new Dictionary<string, TableMapping>();
}
TableMapping map;
if (!_mappings.TryGetValue(type.FullName, out map))
{
map = new TableMapping(type, createFlags);
_mappings[type.FullName] = map;
}
return map;
}
}
答案 2 :(得分:0)
试试这个:
if (!_mappings.ContainsKey(type.FullName))
{
_mappings.Add(map);
}
_mappings [type.FullName] = map;