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