4

Xamarin.Forms アプリケーションがあり、App クラスに次のコードがあります (はい、これは問題を示すための単なるサンプルです)。

    public App()
    {
        BlobCache.ApplicationName = "MyApp";
        BlobCache.EnsureInitialized();


        // The root page of your application
        MainPage = GetMainPage();
    }

    public object BlockingGetExternalUser()
    {
        return GetExternalUser().Result;
    }

    private async Task<object> GetExternalUser()
    {
        try
        {
            return await BlobCache.LocalMachine.GetObject<object>("user");
        }
        catch (KeyNotFoundException)
        {
            return null;
        }
    }

キー「ユーザー」が存在しないため、KeyNotFoundException が発生することが予想されます。ただし、この例外がスローされることはありません。代わりに、単に「ハング」し、await GetObject 呼び出しから戻ることはありません。

Android 5.0を搭載した携帯電話でこれを実行しています。

これを修正する方法はありますか?私は根本的に間違ったことをしていますか?

更新: 補足: すぐに GetObject を試す代わりに、キーが実際にキャッシュに存在するかどうかを確認してから、キャッシュから取得することもできます。ただし、私が間違っていなければ、上記のサンプルのように GetObject を呼び出して例外をキャッチする以外にチェックを行う方法はありません。アイテムが存在するかどうかを知りたいだけのシナリオでは、それは理想的ではないようです。「Exists()」メソッドは、Akavache にあると便利でしょうか? それとも、何かが足りないのでしょうか?

Update2: コンストラクターで非同期メソッドを使用しないように例を変更します。それが問題ではないという点を証明するためだけに。

Update3: コンストラクターから呼び出しを削除します。コード内の任意の場所から BlockingGetExternalUser を呼び出すと、待機がまだハングします。

4

2 に答える 2

1

コンストラクター ( ) で非同期メソッドを使用することvar externalUser = GetExternalUser().Result;は、悪いコードと見なされます。クラス コンストラクターで非同期メソッドを使用しないでください。これを読んでください:コンストラクターを非同期にすることはできますか?

デッドロックを回避するために変更を試みることができます。

Func<Task> task = async () => { await GetExternalUser().ConfigureAwait(false); };
task().Wait();

…が、お勧めしません。

于 2015-07-15T15:58:53.770 に答える