如果您想使用Azure,最简单的方法是使用
Windows Azure移动服务。它允许您在几分钟内使用Web界面设置数据库和Web服务。
这很酷,允许您向您的Web API逻辑添加自定义JavaScript,并生成JSON Web API。有Windows 8、Windows Phone和iOS的客户端库。您可以轻松地为任何启用HTTP的前端编写自己的。
但是请注意,选择云路线意味着您的应用程序将无法脱机工作(如果您不编写缓存系统的话。而缓存需要本地DB)。
关于本地DB:
您真的有两种可能性:
1)在应用程序中使用真正的DB,如SQLite。它作为
Nuget包可用,但现在ARM支持不是开箱即用的,也不被团队保证。如果您不需要ARM,请尝试一下:)
2)像以前一样使用普通的文件存储。我个人经常这样做。但是当从不同的线程访问它时会遇到问题(Access Denied错误)。
当您将东西存储在本地文件中时,请不要忘记锁定关键部分(即在读取或写入文件时)以防止访问被拒绝的异常。为了确保,将您的写入/读取逻辑封装在应用程序中唯一的服务类实例中。(例如使用单例模式或任何等效方法)。
现在是锁本身。我想您正在使用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字段(来自我自己的项目之一):
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;
}
}
}