我们正在使用Xamarin为安卓和ios编写C#代码和SQLite。然而,关于如何使用sqlite,我似乎有一个概念上的误解:
What are the best practices for SQLite on Android?
根据stackoverflow的答案,它说-一个助手和一个数据库连接。在它周围使用lock,以确保任何时候只有一个线程访问sqlite db。
我的问题是-如果是这样的话-异步有什么用?
我尝试将异步与同步代码一起使用--代码正确地给了我编译错误以避免死锁。
Why can't I use the 'await' operator within the body of a lock statement?
public async Task InsertAsync<T> (T item){
lock (mutex) {
await asyncConnection.InsertAsync (item);
}
}
public async Task InsertOrUpdateAsync<T> (T item){
lock (mutex) {
int count = await asyncConnection.UpdateAsync (item);
if (0 == count) {
await asyncConnection.InsertAsync (item);
}
}
}失败。然而,如果我打算使用锁来确保在sqlite中一次一个线程地使用一个连接作为最佳实践,那么为什么会有异步sqlite库呢?
为什么一些线程会在web上推广异步sqlite的使用。
在android和iphone中sqlite的最佳实践是什么?正在使用同步版本吗?
发布于 2014-06-13 08:10:42
同步和异步之间以及单个和并发之间有很大的区别,它们都有四种组合。
在单个异步的情况下,您最多使用单个线程访问DB,但是在整个操作过程中它不需要是同一个线程,并且当您不需要线程时(当您等待IO操作完成时),您根本不需要任何线程。
将async使用限制为一次只能执行一个操作的最基本方法是将SemaphoreSlim与initialCount = 1一起使用。更好的方法是使用AsyncLock ( Stephen Toub的Building Async Coordination Primitives, Part 6: AsyncLock):
private readonly AsyncLock _lock = new AsyncLock();
public async Task InsertAsync<T> (T item)
{
using(await _lock.LockAsync())
{
await asyncConnection.InsertAsync (item);
}
}
public async Task InsertOrUpdateAsync<T> (T item)
{
using(await _lock.LockAsync())
{
if (0 == await asyncConnection.UpdateAsync (item))
{
await asyncConnection.InsertAsync (item);
}
}
}发布于 2014-06-12 22:28:12
您的数据库不接受多次访问(插入、更新等)。并不意味着针对它工作的单个线程必须使用阻塞api。
如果你不需要跨进程锁定,你可以在异步方法中使用SemaphoreSlim.WaitAsync而不是Mutex来异步等待锁:
private readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(initialCount: 1);
public async Task InsertAsync<T>(T item)
{
await semaphoreSlim.WaitAsync();
try
{
await asyncConnection.InsertAsync(item);
}
finally
{
semaphoreSlim.Release();
}
}
public async Task InsertOrUpdateAsync<T>(T item)
{
await semaphoreSlim.WaitAsync();
try
{
int count = await asyncConnection.UpdateAsync(item);
if (0 == count)
{
await asyncConnection.InsertAsync(item);
}
}
finally
{
semaphoreSlim.Release();
}
}https://stackoverflow.com/questions/24186577
复制相似问题