首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sqlite on locking或async的正确用法是什么

sqlite on locking或async的正确用法是什么
EN

Stack Overflow用户
提问于 2014-06-12 22:10:10
回答 2查看 9.8K关注 0票数 5

我们正在使用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?

代码语言:javascript
复制
    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的最佳实践是什么?正在使用同步版本吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-13 08:10:42

同步和异步之间以及单个和并发之间有很大的区别,它们都有四种组合。

在单个异步的情况下,您最多使用单个线程访问DB,但是在整个操作过程中它不需要是同一个线程,并且当您不需要线程时(当您等待IO操作完成时),您根本不需要任何线程。

async使用限制为一次只能执行一个操作的最基本方法是将SemaphoreSliminitialCount = 1一起使用。更好的方法是使用AsyncLock ( Stephen Toub的Building Async Coordination Primitives, Part 6: AsyncLock):

代码语言:javascript
复制
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);
        }
    }
}

注:My implementation of AsyncLock

票数 7
EN

Stack Overflow用户

发布于 2014-06-12 22:28:12

您的数据库不接受多次访问(插入、更新等)。并不意味着针对它工作的单个线程必须使用阻塞api。

如果你不需要跨进程锁定,你可以在异步方法中使用SemaphoreSlim.WaitAsync而不是Mutex来异步等待锁:

代码语言:javascript
复制
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();
   }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24186577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档