4

私は現在、いくつかのテーブルを保存する必要がある Windows 8 アプリに取り組んでいます。現在、目的を解決するために XDocument クラスで XML ファイルを使用しています。andなどを使用するsaveandloadメソッドを使用します。さらに、 thereとメソッドは異なるイベントによって呼び出されます。ただし、呼び出しが繰り返されるたびに、ファイル アクセスが拒否されたことを示す例外がスローされます。予想される動作 -詳細はこちら! これを回避する汚い方法 (ロックなどを使用するなど) はありますが、私は結果にあまり満足していません。私はむしろデータベースを好むでしょう。さらに、データを利用する Windows Phone 8 (およびおそらく Web バージョン) 用の別のアプリを作成することを計画しています。GetFileAsyncCreateFileAsyncsaveload

彼らは、Windows 8 はクラウド ベースであると繰り返し言っています。質問: データを保存する正しい方法は何ですか? XML は正しいように見えますが、上で述べた問題があります。Windows 8、Windows Phone 8、そして場合によっては Azure を含む理想的なクラウド ベースのソリューションは何ですか? 私が望むのは、テーブルを保存してそれらにアクセスできるようにすることだけです。

質問が不明確に思われる場合は申し訳ありません。必要に応じて情報を提供します。

4

5 に答える 5

7

Azure を使用する場合、最も簡単な方法はWindows Azure モバイル サービスです。Web インターフェイスを使用して数分でデータベースと Web サービスをセットアップできます。

これは非常に優れており、カスタム JavaScript を Web API ロジックに追加し、json Web API を生成できます。Windows 8、Windows Phone、および iOS 用のクライアント ライブラリがあります。http が有効なフロントエンドについては、簡単に独自のロールを作成できます。

ただし、クラウド ルートを使用すると、アプリがオフラインで動作しないことを意味することに注意してください (キャッシュ システムをコーディングしない場合。キャッシュにはローカル DB が必要になります)。

ローカル DB について 実際には可能性があります: 1) SQLite のようなアプリ内の実際の DB。これはNuget パッケージとして利用できますが、現時点では ARM サポートはそのままでは利用できず、チームによって保証されていません。腕が必要ない場合は、試してみてください:)

2)以前と同じように、昔ながらのファイルストレージ。私は個人的にそれを自分で行うことがよくあります。ただし、別のスレッドからアクセスすると問題が発生します (アクセス拒否エラー)。

ローカル ファイルに保存するときは、クリティカル セクションをロックすることを忘れないでください (つまり、ファイルを読み書きするとき)。これにより、アクセス拒否の例外が発生しなくなります。確かに、アプリ内で一意のサービス クラス インスタンスに書き込み/読み取りロジックをカプセル化します。(たとえば、シングルトンパターン、または同等のものを使用してください)。

今、ロック自体。async await を使用していると思います。私もこの甘いものが好きです。ただし、従来の C# ロック (lockたとえば、キーワードを使用) は、async await では機能しません。(たとえそれが機能したとしても、ブロッキングはクールではありません)。

素晴らしい AsyncLock が登場するのはそのためです。これはロックですが、ほぼブロックされません (待機します)。

public class AsyncLock
{
    private readonly AsyncSemaphore m_semaphore;
    private readonly Task<Releaser> m_releaser;

    public AsyncLock()
    {
        m_semaphore = new AsyncSemaphore(1);
        m_releaser = Task.FromResult(new Releaser(this));
    }

    public Task<Releaser> LockAsync()
    {
        var wait = m_semaphore.WaitAsync();
        return wait.IsCompleted ?
            m_releaser :
            wait.ContinueWith((_, state) => new Releaser((AsyncLock)state),
                this, CancellationToken.None,
                TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
    }

    public struct Releaser : IDisposable
    {
        private readonly AsyncLock m_toRelease;

        internal Releaser(AsyncLock toRelease) { m_toRelease = toRelease; }

        public void Dispose()
        {
            if (m_toRelease != null)
                m_toRelease.m_semaphore.Release();
        }
    }
}

public class AsyncSemaphore
{
    private readonly static Task s_completed = Task.FromResult(true);
    private readonly Queue<TaskCompletionSource<bool>> m_waiters = new Queue<TaskCompletionSource<bool>>();
    private int m_currentCount;

    public AsyncSemaphore(int initialCount)
    {
        if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount");
        m_currentCount = initialCount;

    }
    public Task WaitAsync()
    {
        lock (m_waiters)
        {
            if (m_currentCount > 0)
            {
                --m_currentCount;
                return s_completed;
            }
            else
            {
                var waiter = new TaskCompletionSource<bool>();
                m_waiters.Enqueue(waiter);
                return waiter.Task;
            }
        }

    }
    public void Release()
    {
        TaskCompletionSource<bool> toRelease = null;
        lock (m_waiters)
        {
            if (m_waiters.Count > 0)
                toRelease = m_waiters.Dequeue();
            else
                ++m_currentCount;
        }
        if (toRelease != null)
            toRelease.SetResult(true);

    }
}

このように使用できます (blogLock という名前の AsyncLock フィールドがあるとします (私自身のプロジェクトの 1 つから取得):

            using (await blogLock.LockAsync())
            {
                using (var stream = await folder.OpenStreamForReadAsync(_blogFileName))
                {
                    using (var reader = new StreamReader(stream))
                    {
                        var json = await reader.ReadToEndAsync();
                        var blog = await JsonConvert.DeserializeObjectAsync<Blog>(json);

                        return blog;
                    }
                }
            }
于 2012-12-01T14:33:48.050 に答える
2

私は基本的にまったく同じ問題を抱えているため、このスレッドに出くわしました。私にとって驚くべきことは、Microsoft が独自のエンタープライズ クラスのデータベース製品 (SQL Server) を作成していることです。これには、軽量で埋め込み可能なバージョンがいくつかありますが、これらは Windows 8/Windows Phone 8 アプリケーションでは使用できないようです。ローカル データベースを提供します。それでもMySQLはできます!

ASP.NET/VB/NET/SQL の経験を活かして、Windows Phone 8 アプリの作成に手を出そうと何度か試みましたが、データ操作を実行するための別の方法を学ぼうとしていつも行き詰まります。 Web 環境で寝ていると興味を失います。W8/WP8 アプリで SQL を使いやすくできないのはなぜですか?

于 2013-08-16T15:57:00.237 に答える
0

これはすでに受け入れられている回答がある古い質問であることは知っていますが、技術的な問題を解決するよりも、依存しないアーキテクチャを使用する方が良いと思うので、石鹸箱を取り出してとにかく回答しますローカルデータベース機能。

私の経験では、デバイスのローカル データベース サービスを必要とするデータはほとんどありません。

ローカル ストレージを必要とするほとんどのユーザー生成データは、非ローミング (つまり、デバイス固有) のユーザー設定と構成 (リムーバブル ストレージ設定の使用など) です。ゲームの結果はこのカテゴリに分類されます。大量のユーザー データを生成するアプリは通常、デスクトップに実装され、ほぼ確実にローカル ネットワークへの高速で信頼性の高い接続を備えているため、サーバー ベースのストレージは、Office ドキュメントのような「ファット」データにも非常に適しています。

参照データは確かにサーバー ベースである必要がありますが、キャッシュすることもできます。Windows Phone 8 の Nokia Maps は、キャッシュされたサーバー ベースのデータの優れた例です。オフラインでの使用を見越して、キャッシュを明示的にプリロードすることもできます。

今説明した世界観は、ローカル SQL Server にはほとんど役に立ちません。クエリ エンジンが必要な場合は、LINQ を使用します。アプリケーション設定とユーザー データをオブジェクト グラフとして表現し、XML を (逆) シリアル化します。ORM クラスを維持したくない場合は、Linq2Xml を XML で直接使用することもできます。

ユーザーのすべてのデバイスで利用できるはずのあらゆる種類のデータは、クラウドに保存する必要があります。


いくつかの akshay のコメントに対処するには、

地図データ

地理空間データは通常、ズームによって変化する詳細レベルを提供するというさまざまな理由から、四分木と呼ばれる構造に編成されます。これらがアクセスおよび操作される方法は、オブジェクト グラフとしての表現からかなりの利点が得られ、ユーザーによって更新されないため、このデータは確かにリレーショナル データベースに格納できますが、コンパイル中はおそらくそうですが、確かにそうではありません。そのように保管または配送されません。

LINQ はクワッド ツリーに直接適用できるため、このシナリオに適しています。

データは確かにファイルにあります。しかし、別のプロセスを介した間接的なアクセスではなく、ファイルへの直接アクセスを意味していたと思います。おそらく、並行性とクエリ処理の問題を一度徹底的に解決するために多大な労力を費やし、その解決策をクライアント アプリ間で共有することは良い考えであると考えているでしょう。しかし、これは非常に重いソリューションであり、クエリ処理の側面は既に LINQ によって適切に処理されています (これが、私が言及し続ける理由です)。

XML の問題

読み取り専用はロックする必要がないため、キャッシュしてシングルトン パターンを使用することにより、ファイル システムのロックの問題を回避します...

public static class XManager 
{
  static Dictionary<string, XDocument> __cache = new Dictionary<string, XDocument>();
  public static XDocument GetXDoc(string filepath)
  {
    if (!__cache.Contains(filepath)
    {
      __cache[filepath] = new XDocument();
      __cache[filepath].Load(filepath);
    }
    return _cache[filepath];
  }
}
于 2014-09-25T08:20:53.070 に答える
0

データがデバイスのユーザーに関連している場合は、SQLlite の使用を検討してください ... SQLlite とローカルの winRT データベースに関するスタックに関する質問がここにあります: WinRT/Metro アプリケーションのローカル データベース ストレージ

于 2012-12-01T15:04:47.570 に答える
0
  1. SQL データベース
  2. Windows 8 および JavaScript 開発の場合の IndexedDB
于 2012-12-01T15:08:56.980 に答える