最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#解決SQlite并發(fā)異常問題的方法(使用讀寫鎖)

 更新時間:2016年07月05日 16:18:51   作者:yacki  
這篇文章主要介紹了C#解決SQlite并發(fā)異常問題的方法,通過使用讀寫鎖達(dá)到多線程安全訪問,進(jìn)而解決SQLite并發(fā)異常的問題,具有一定參考借鑒價值,需要的朋友可以參考下

本文實例講述了C#解決SQlite并發(fā)異常問題的方法。分享給大家供大家參考,具體如下:

使用C#訪問sqlite時,常會遇到多線程并發(fā)導(dǎo)致SQLITE數(shù)據(jù)庫損壞的問題。

SQLite是文件級別的數(shù)據(jù)庫,其鎖也是文件級別的:多個線程可以同時讀,但是同時只能有一個線程寫。Android提供了SqliteOpenHelper類,加入Java的鎖機制以便調(diào)用。但在C#中未提供類似功能。

作者利用讀寫鎖(ReaderWriterLock),達(dá)到了多線程安全訪問的目標(biāo)。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SQLite;
using System.Threading;
using System.Data;
namespace DataAccess
{
/////////////////
public sealed class SqliteConn
{
  private bool m_disposed;
  private static Dictionary<String, SQLiteConnection> connPool =
    new Dictionary<string, SQLiteConnection>();
  private static Dictionary<String, ReaderWriterLock> rwl =
    new Dictionary<String, ReaderWriterLock>();
  private static readonly SqliteConn instance = new SqliteConn();
  private static string DEFAULT_NAME = "LOCAL";
  #region Init
  // 使用單例,解決初始化與銷毀時的問題
  private SqliteConn()
  {
    rwl.Add("LOCAL", new ReaderWriterLock());
    rwl.Add("DB1", new ReaderWriterLock());
    connPool.Add("LOCAL", CreateConn("\\local.db"));
    connPool.Add("DB1", CreateConn("\\db1.db"));
    Console.WriteLine("INIT FINISHED");
  }
  private static SQLiteConnection CreateConn(string dbName)
  {
    SQLiteConnection _conn = new SQLiteConnection();
    try
    {
      string pstr = "pwd";
      SQLiteConnectionStringBuilder connstr = new SQLiteConnectionStringBuilder();
      connstr.DataSource = Environment.CurrentDirectory + dbName;
      _conn.ConnectionString = connstr.ToString();
      _conn.SetPassword(pstr);
      _conn.Open();
      return _conn;
    }
    catch (Exception exp)
    {
      Console.WriteLine("===CONN CREATE ERR====\r\n{0}", exp.ToString());
      return null;
    }
  }
  #endregion
  #region Destory
  // 手動控制銷毀,保證數(shù)據(jù)完整性
  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
  protected void Dispose(bool disposing)
  {
    if (!m_disposed)
    {
      if (disposing)
      {
        // Release managed resources
        Console.WriteLine("關(guān)閉本地DB連接...");
        CloseConn();
      }
      // Release unmanaged resources
      m_disposed = true;
    }
  }
  ~SqliteConn()
  {
    Dispose(false);
  }
  public void CloseConn()
  {
    foreach (KeyValuePair<string, SQLiteConnection> item in connPool)
    {
      SQLiteConnection _conn = item.Value;
      String _connName = item.Key;
      if (_conn != null && _conn.State != ConnectionState.Closed)
      {
        try
        {
          _conn.Close();
          _conn.Dispose();
          _conn = null;
          Console.WriteLine("Connection {0} Closed.", _connName);
        }
        catch (Exception exp)
        {
          Console.WriteLine("嚴(yán)重異常: 無法關(guān)閉本地DB {0} 的連接。", _connName);
          exp.ToString();
        }
        finally
        {
          _conn = null;
        }
      }
    }
  }
  #endregion
  #region GetConn
  public static SqliteConn GetInstance()
  {
    return instance;
  }
  public SQLiteConnection GetConnection(string name)
  {
    SQLiteConnection _conn = connPool[name];
    try
    {
      if (_conn != null)
      {
        Console.WriteLine("TRY GET LOCK");
        //加鎖,直到釋放前,其它線程無法得到conn
        rwl[name].AcquireWriterLock(3000);
        Console.WriteLine("LOCK GET");
        return _conn;
      }
    }
    catch (Exception exp)
    {
      Console.WriteLine("===GET CONN ERR====\r\n{0}", exp.StackTrace);
    }
    return null;
  }
  public void ReleaseConn(string name)
  {
    try
    {
      //釋放
      Console.WriteLine("RELEASE LOCK");
      rwl[name].ReleaseLock();
    }
    catch (Exception exp)
    {
      Console.WriteLine("===RELEASE CONN ERR====\r\n{0}", exp.StackTrace);
    }
  }
  public SQLiteConnection GetConnection()
  {
    return GetConnection(DEFAULT_NAME);
  }
  public void ReleaseConn()
  {
    ReleaseConn(DEFAULT_NAME);
  }
  #endregion
}
}
////////////////////////

調(diào)用的代碼如下:

SQLiteConnection conn = null;
try
{
  conn = SqliteConn.GetInstance().GetConnection();
  //在這里寫自己的代碼
}
finally
{
  SqliteConn.GetInstance().ReleaseConn();
}

值得注意的是,每次申請連接后,必須使用ReleaseConn方法釋放,否則其它線程就再也無法得到連接了。

安全起見,在作者寫的這個工具類中,啟用了最嚴(yán)格的讀寫鎖限制(即在寫入時無法讀?。?。如果數(shù)據(jù)讀取頻繁,讀者亦可開發(fā)一個得到只讀連接的方法以提高性能。

在Winxp/Win7/Win8/Win8.1 32/64位下測試通過。

更多關(guān)于C#相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《C#程序設(shè)計之線程使用技巧總結(jié)》、《C#操作Excel技巧總結(jié)》、《C#中XML文件操作技巧匯總》、《C#常見控件用法教程》、《WinForm控件用法總結(jié)》、《C#數(shù)據(jù)結(jié)構(gòu)與算法教程》、《C#數(shù)組操作技巧總結(jié)》及《C#面向?qū)ο蟪绦蛟O(shè)計入門教程

希望本文所述對大家C#程序設(shè)計有所幫助。

相關(guān)文章

  • C#調(diào)用mmpeg進(jìn)行各種視頻轉(zhuǎn)換的類實例

    C#調(diào)用mmpeg進(jìn)行各種視頻轉(zhuǎn)換的類實例

    這篇文章主要介紹了C#調(diào)用mmpeg進(jìn)行各種視頻轉(zhuǎn)換的類,實例分析了C#調(diào)用mmpeg操作視頻文件的技巧,非常具有實用價值,需要的朋友可以參考下
    2015-03-03
  • 基于C#實現(xiàn)的端口掃描器實例代碼

    基于C#實現(xiàn)的端口掃描器實例代碼

    這篇文章主要介紹了基于C#實現(xiàn)的端口掃描器實例代碼,需要的朋友可以參考下
    2014-07-07
  • C#中字符串合并的多種實現(xiàn)方法

    C#中字符串合并的多種實現(xiàn)方法

    字符串合并是將兩個或多個字符串組合成一個單一字符串的過程,在項目開發(fā)中非常常見,C#也為我們提供非常多字符串合并方式,下面一起盤點下,感興趣的小伙伴跟著小編一起來看看吧
    2025-01-01
  • 使用c#實現(xiàn)隨機數(shù)猜數(shù)游戲的示例代碼

    使用c#實現(xiàn)隨機數(shù)猜數(shù)游戲的示例代碼

    這篇文章主要介紹了使用c#實現(xiàn)隨機數(shù)猜數(shù)游戲的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • C#繪制柱狀圖和折線圖的方法

    C#繪制柱狀圖和折線圖的方法

    這篇文章主要為大家詳細(xì)介紹了C#繪制柱狀圖和折線圖的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C#連接MySQL的兩個簡單代碼示例

    C#連接MySQL的兩個簡單代碼示例

    這篇文章主要介紹了C#連接MySQL的簡單代碼示例,需要的朋友可以參考下
    2017-06-06
  • C#簡單遍歷指定文件夾中所有文件的方法

    C#簡單遍歷指定文件夾中所有文件的方法

    這篇文章主要介紹了C#簡單遍歷指定文件夾中所有文件的方法,結(jié)合實例形式分析了文件夾與文件遍歷的技巧,并附帶說明了文件與文件夾操作的常用函數(shù),需要的朋友可以參考下
    2016-06-06
  • C#如何遍歷Dictionary

    C#如何遍歷Dictionary

    這篇文章主要為大家詳細(xì)介紹了C#遍歷Dictionary的方法,.NET中的Dictionary是鍵/值對的集合,使用起來比較方便,Dictionary也可以用KeyValuePair來迭代遍歷,感興趣的小伙伴們可以參考一下
    2016-04-04
  • 90分鐘實現(xiàn)一門編程語言(極簡解釋器教程)

    90分鐘實現(xiàn)一門編程語言(極簡解釋器教程)

    本文介紹了如何使用 C# 實現(xiàn)一個簡化 Scheme——iScheme 及其解釋器,需要的朋友可以參考下
    2016-12-12
  • 淺談C#六大設(shè)計原則

    淺談C#六大設(shè)計原則

    這篇文章主要介紹了C#六大設(shè)計原則的相關(guān)內(nèi)容,文中代碼非常細(xì)致,供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06

最新評論

鄂伦春自治旗| 玛纳斯县| 江川县| 同江市| 永吉县| 昔阳县| 伊金霍洛旗| 祁连县| 南宁市| 缙云县| 高台县| 宁远县| 保德县| 灵宝市| 景东| 新泰市| 勃利县| 广东省| 化隆| 赣榆县| 万盛区| 永寿县| 平江县| 筠连县| 梧州市| 潮州市| 达州市| 广南县| 枣阳市| 松滋市| 威海市| 杭州市| 平乡县| 瓮安县| 沈丘县| 临安市| 乳源| 伊通| 夏邑县| 娄烦县| 濮阳县|