3

ConfigurationWin8アプリを作成したいのですが、そこでstaticは、起動時に一度読み込まれ、実行時にどこからでもアクセスできるメンバーで -class を使用します。

したがって、主な問題は、デフォルト設定が xml ファイル内に保存されていることですが、ファイルの内容の読み取りは非同期 ( StorageFile) ですが、使用できないため、ファイルが完全に読み込まれるまで待機する解決策が見つかりません。awaitすべての状況 (メイン スレッド、コンストラクター) で、私には設計上の問題のように見えます。データにアクセスする前にファイルが完全に読み取られないConfigurationと、このアプリの動作が正しくなくなります。

ここにコード例があります:

public class Configuration
{
    // stores the only instance of this class
    private Configuration instance = null;

    // public access to the instance
    public Configuration Current
    {
        get
        {
            if (instance == null)
            {
                instance = new Configuration();
            }

            return instance;
        }
    }

    private Configuration()
    {
        // load data from file synchronously
        // so it is loaded once on first access
    }
}

この問題を解決する方法がわかりません。おそらく、クラスの設計を変更する必要がありConfigurationます。どんな提案/ヒントもいいでしょう。

4

2 に答える 2

4

アプリケーションの応答性を高めるために、50 ミリ秒を超える可能性のある同期呼び出し (ファイルまたはネットワーク IO 呼び出し) を許可しないという設計上の決定がありました。

コンストラクターからの非同期呼び出しはできませんawaitが、完了するのを待たずにそのような呼び出しを開始することを妨げるものは何もありません。

private Configuration()
{
    Init();
}

private async void Init()
{
    var contents = await FileIO.ReadTextAsync(file);
}

Configurationその後、内部からプロパティを設定できますInit()。を実装INotifyPropertyChangedすると、値が読み込まれる前に値を UI にバインドでき、読み込まれると UI が更新されます。

アプリのある時点で操作が完了するのを確認または待機する必要がある場合は、 の署名Init()を returnに変更できTaskます。

private Configuration()
{
    InitTask = Init();
}

private async Task Init()
{
    var contents = await FileIO.ReadTextAsync(file);
}

public Task InitTask { get; private set; }

これで、完了したかどうかを確認できます。

if (Configuration.Current.IsCompleted)
{
    //
}

またはそれもawait(すでに完了している場合、これはすぐにTask完了します):

await Configuration.Current.InitTask;

編集:

上記のファイルが読み込まれるまでユーザーに何も表示する意味がない場合は、エントリ ページを変更して別の「ビュー」にすることができます。

  • 実際のビュー (アプリの準備ができたときにユーザーに確認してもらいたい)
  • スプラッシュ スクリーン ビュー (進行状況インジケーターの表示など)

IsCompleted実装されたビューモデルで公開する必要があるプロパティに基づいて、適切なものを表示することができますINotifyPropertyChanged

次に、次のようにページを設計できます。

<Page xmlns:common="using:MyApp.Common">
    <Page.Resources>
        <common:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
    </Page.Resources>
    <Grid>
        <Grid Visibility="{Binding Configuration.IsCompleted, Converter={StaticResource BoolToVisibilityConverter}">
            <!-- put your actual view here -->
        </Grid>
        <Grid Visibility="{Binding Configuration.IsNotCompleted, Converter={StaticResource BoolToVisibilityConverter}">
            <!-- put your splash screen view here -->
        </Grid>
    </Grid>
</Page>
于 2013-04-30T04:35:54.627 に答える
1

設定を保存するために別のクラスは必要ありませんAplicationData.Current.LocalSettings。アプリが起動されるたびに自動的に読み込まれるすべての Windows 8 アプリケーションに提供される辞書があり、awaitキーワードなしでそれを読み取ります。次に例を示します。

var settings = ApplicationData.Current.LocalSettings;
settings.Values["MyIndex"] = 2;

object value = settings.Values["MyIndex"];
if (value != null)
{
     int myIndex = (int)value;
     //...
}
于 2013-04-29T09:10:44.937 に答える