C# SQLite Net PCL死锁问题
我将SQLite PCL与Xamarin.Android一起用于数据存储。我正在异步使用它,因此遇到了死锁问题 该实现包含在C# SQLite Net PCL死锁问题,c#,sqlite,asynchronous,xamarin,xamarin.android,C#,Sqlite,Asynchronous,Xamarin,Xamarin.android,我将SQLite PCL与Xamarin.Android一起用于数据存储。我正在异步使用它,因此遇到了死锁问题 该实现包含在数据处理程序类中: 构造函数 public DataHandler(string path) { _db = new SQLiteAsyncConnection(path); Initialize().Wait(); } 初始化函数 private async Task Initialize() { using (await Lock())
数据处理程序类中:
构造函数
public DataHandler(string path)
{
_db = new SQLiteAsyncConnection(path);
Initialize().Wait();
}
初始化函数
private async Task Initialize()
{
using (await Lock())
{
await _db.CreateTableAsync<Person>();
await _db.CreateTableAsync<Animal>();
}
}
专用异步任务初始化()
{
使用(wait Lock())
{
等待_db.CreateTableAsync();
等待_db.CreateTableAsync
在构造对象时,会调用Initialize().Wait()
,并在第一次调用CreateTableAsync()
时死锁。不幸的是,如果不涉及对库的反汇编,我就无法真正调试到库中。我使用的异步模式是错误的还是什么?是的,我知道Wait()是同步的。这只是为了与类中的其他方法保持相同的格式。对于此类问题,常见的模式是使用异步工厂方法创建受影响的类
public class DataHandler {
//...other code
private DataHandler() {
}
private async Task InitializeAsync(string path) {
_db = new SQLiteAsyncConnection(path);
using (await Lock()) {
await _db.CreateTableAsync<Person>();
await _db.CreateTableAsync<Animal>();
}
}
public static async Task<DataHandler> CreateDataHandler(string path) {
var handler = new DataHandler();
await handler.InitializeAsync(path);
return handler;
}
//...other code
}
并在实际的偶数处理程序上调用异步代码
private async void Page_Appearing(object sender, EventArgs e) {
//...call async code here
var handler = await DataHandler.CreateDataHandler("<path here>");
//..do what you need to do with the handler.
//unsubscribing from the event
this.Appearing -= Page_Appearing;
}
private async void页面\u出现(对象发送方,事件参数e){
//…在此调用异步代码
var handler=await DataHandler.CreateDataHandler(“”);
//…做你需要处理的事情。
//取消订阅活动
this.beging-=出现的页面;
}
仅当您捕获同步上下文(默认情况下使用async完成)时,它才会死锁。您必须在所有可等待的调用上使用ConfigureAwait(false)来声明您不想捕获同步上下文。请阅读Stephen Cleary及其他关于async/await的所有其他文章
protected override void OnAppearing() {
this.Appearing += Page_Appearing;
}
private async void Page_Appearing(object sender, EventArgs e) {
//...call async code here
var handler = await DataHandler.CreateDataHandler("<path here>");
//..do what you need to do with the handler.
//unsubscribing from the event
this.Appearing -= Page_Appearing;
}