Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SQLite Net PCL死锁问题_C#_Sqlite_Asynchronous_Xamarin_Xamarin.android - Fatal编程技术网

C# SQLite Net PCL死锁问题

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())

我将SQLite PCL与Xamarin.Android一起用于数据存储。我正在异步使用它,因此遇到了死锁问题

该实现包含在
数据处理程序
类中:

构造函数

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;
}