自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C#中SQLite的并發(fā)控制與多線程訪問

數(shù)據(jù)庫 其他數(shù)據(jù)庫
SQLite的并發(fā)控制需要謹(jǐn)慎處理。通過合理的鎖機(jī)制、信號(hào)量控制和異步編程,可以有效管理多線程環(huán)境下的數(shù)據(jù)庫訪問。關(guān)鍵在于平衡線程安全性和性能。

并發(fā)控制的重要性

在多線程環(huán)境中訪問SQLite數(shù)據(jù)庫時(shí),并發(fā)控制至關(guān)重要。不當(dāng)?shù)牟l(fā)訪問可能導(dǎo)致數(shù)據(jù)不一致、競態(tài)條件和潛在的數(shù)據(jù)損壞。本文將詳細(xì)探討C#中SQLite的并發(fā)控制策略。

準(zhǔn)備環(huán)境

安裝 SQLite

首先,你需要在你的 C# 項(xiàng)目中安裝 SQLite 的 NuGet 包:

`Install-Package System.Data.SQLite`

圖片圖片

基本并發(fā)控制機(jī)制

鎖機(jī)制示例

using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppLiteSql
{
    publicclass DatabaseManager
    {
        // 創(chuàng)建一個(gè)靜態(tài)鎖對(duì)象,確保線程同步
        privatestatic readonly object _lock = new object();

        // 數(shù)據(jù)庫連接字符串
        privatestring _connectionString;

        public DatabaseManager(string dbPath)
        {
            _connectionString = $"Data Source={dbPath};Versinotallow=3;";
        }

        // 線程安全的插入方法
        public void ThreadSafeInsert(string name, int age)
        {
            // 使用鎖確保同步
            lock (_lock)
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    connection.Open();
                    using (var command = new SQLiteCommand(connection))
                    {
                        command.CommandText = @"
                        INSERT INTO Users (Name, Age) 
                        VALUES (@Name, @Age)";

                        command.Parameters.AddWithValue("@Name", name);
                        command.Parameters.AddWithValue("@Age", age);

                        command.ExecuteNonQuery();
                    }
                }
            }
        }

        // 線程安全的查詢方法
        public int GetUserCount()
        {
            lock (_lock)
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    connection.Open();
                    using (var command = new SQLiteCommand("SELECT COUNT(*) FROM Users", connection))
                    {
                        return Convert.ToInt32(command.ExecuteScalar());
                    }
                }
            }
        }
    }
}
namespace AppLiteSql
{
    internal class Program
    {
        static void Main(string[] args)
        {
            DatabaseManager dbManager = new DatabaseManager("D:\\myproject\\11Test\\AppLiteSql\\db");
            // 創(chuàng)建多個(gè)線程并發(fā)插入數(shù)據(jù)
            var threads = new List<Thread>();
            for (int i = 0; i < 10; i++)
            {
                int threadId = i;
                var thread = new Thread(() =>
                {
                    for (int j = 0; j < 100; j++)
                    {
                        dbManager.ThreadSafeInsert($"User_{threadId}_{j}", 30 + threadId);
                    }
                });

                threads.Add(thread);
                thread.Start();
            }

            // 等待所有線程完成
            foreach (var thread in threads)
            {
                thread.Join();
            }

            // 驗(yàn)證插入結(jié)果
            int totalUsers = dbManager.GetUserCount();
            Console.WriteLine($"Total Users: {totalUsers}");
        }
    }
}

圖片圖片

高級(jí)并發(fā)控制策略

信號(hào)量控制數(shù)據(jù)庫連接池

using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppLiteSql
{
    publicclass AdvancedDatabaseManager
    {
        // 使用信號(hào)量控制并發(fā)連接數(shù)  
        private readonly SemaphoreSlim _connectionSemaphore;
        privatestring _connectionString;

        public AdvancedDatabaseManager(string dbPath, int maxConcurrentConnections = 5)
        {
            _connectionString = $"Data Source={dbPath};Versinotallow=3;";
            _connectionSemaphore = new SemaphoreSlim(maxConcurrentConnections);
        }

        // 異步并發(fā)查詢方法  
        public async Task<int> ConcurrentQueryAsync(string query)
        {
            await _connectionSemaphore.WaitAsync();
            try
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    await connection.OpenAsync();
                    using (var command = new SQLiteCommand(query, connection))
                    {
                        return Convert.ToInt32(await command.ExecuteScalarAsync());
                    }
                }
            }
            finally
            {
                _connectionSemaphore.Release();
            }
        }

        // 異步讀取多行數(shù)據(jù)的方法  
        public async Task<List<User>> ReadUsersAsync(string condition = null)
        {
            await _connectionSemaphore.WaitAsync();
            try
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    await connection.OpenAsync();

                    string query = "SELECT Id, Name, Age FROM Users";
                    if (!string.IsNullOrEmpty(condition))
                    {
                        query += $" WHERE {condition}";
                    }

                    using (var command = new SQLiteCommand(query, connection))
                    {
                        var users = new List<User>();
                        using (var reader = await command.ExecuteReaderAsync())
                        {
                            while (await reader.ReadAsync())
                            {
                                users.Add(new User
                                {
                                    Id = reader.GetInt32(0),
                                    Name = reader.GetString(1),
                                    Age = reader.GetInt32(2)
                                });
                            }
                        }
                        return users;
                    }
                }
            }
            finally
            {
                _connectionSemaphore.Release();
            }
        }

        // 異步寫入數(shù)據(jù)的方法  
        public async Task<int> WriteUserAsync(User user)
        {
            await _connectionSemaphore.WaitAsync();
            try
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    await connection.OpenAsync();
                    using (var command = new SQLiteCommand(connection))
                    {
                        command.CommandText = @"  
                        INSERT INTO Users (Name, Age)   
                        VALUES (@Name, @Age);  
                        SELECT last_insert_rowid();";

                        command.Parameters.AddWithValue("@Name", user.Name);
                        command.Parameters.AddWithValue("@Age", user.Age);

                        return Convert.ToInt32(await command.ExecuteScalarAsync());
                    }
                }
            }
            finally
            {
                _connectionSemaphore.Release();
            }
        }

        // 異步批量寫入數(shù)據(jù)的方法  
        public async Task BulkWriteUsersAsync(List<User> users)
        {
            await _connectionSemaphore.WaitAsync();
            try
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    await connection.OpenAsync();
                    using (var transaction = connection.BeginTransaction())
                    {
                        try
                        {
                            using (var command = new SQLiteCommand(connection))
                            {
                                command.CommandText = @"  
                                INSERT INTO Users (Name, Age)   
                                VALUES (@Name, @Age)";

                                var nameParam = command.Parameters.Add("@Name", System.Data.DbType.String);
                                var ageParam = command.Parameters.Add("@Age", System.Data.DbType.Int32);

                                foreach (var user in users)
                                {
                                    nameParam.Value = user.Name;
                                    ageParam.Value = user.Age;
                                    await command.ExecuteNonQueryAsync();
                                }
                            }

                            await transaction.CommitAsync();
                        }
                        catch
                        {
                            await transaction.RollbackAsync();
                            throw;
                        }
                    }
                }
            }
            finally
            {
                _connectionSemaphore.Release();
            }
        }

        // 異步更新數(shù)據(jù)的方法  
        public async Task<int> UpdateUserAsync(int id, User updatedUser)
        {
            await _connectionSemaphore.WaitAsync();
            try
            {
                using (var connection = new SQLiteConnection(_connectionString))
                {
                    await connection.OpenAsync();
                    using (var command = new SQLiteCommand(connection))
                    {
                        command.CommandText = @"  
                        UPDATE Users   
                        SET Name = @Name, Age = @Age   
                        WHERE Id = @Id";

                        command.Parameters.AddWithValue("@Name", updatedUser.Name);
                        command.Parameters.AddWithValue("@Age", updatedUser.Age);
                        command.Parameters.AddWithValue("@Id", id);

                        return await command.ExecuteNonQueryAsync();
                    }
                }
            }
            finally
            {
                _connectionSemaphore.Release();
            }
        }
    }

}
namespace AppLiteSql
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            AdvancedDatabaseManager dbManager = new AdvancedDatabaseManager("D:\\myproject\\11Test\\AppLiteSql\\db");
            // 寫入單個(gè)用戶  
            var newUser = new User { Name = "John Doe", Age = 30 };
            int newUserId = await dbManager.WriteUserAsync(newUser);

            // 批量寫入用戶  
            var userList = new List<User>
            {
                new User { Name = "Alice", Age = 25 },
                new User { Name = "Bob", Age = 35 }
            };
            await dbManager.BulkWriteUsersAsync(userList);

            // 讀取用戶  
            var users = await dbManager.ReadUsersAsync("Age > 20");
            foreach (var user in users)
            {
                Console.WriteLine($"User: {user.Name}, Age: {user.Age}");
            }

            // 更新用戶  
            var updatedUser = new User { Name = "John Smith", Age = 31 };
            await dbManager.UpdateUserAsync(newUserId, updatedUser);
        }
    }
}

圖片圖片

最佳實(shí)踐與注意事項(xiàng)

  1. 始終使用參數(shù)化查詢防止SQL注入
  2. 盡量縮小鎖的作用范圍
  3. 考慮使用異步方法處理數(shù)據(jù)庫操作
  4. 對(duì)于高并發(fā)場景,考慮使用連接池
  5. 定期檢查和優(yōu)化數(shù)據(jù)庫性能

性能建議

  • 對(duì)于讀多寫少的場景,考慮使用讀寫鎖
  • 使用批量插入減少數(shù)據(jù)庫連接開銷
  • 優(yōu)化查詢語句和索引

總結(jié)

SQLite的并發(fā)控制需要謹(jǐn)慎處理。通過合理的鎖機(jī)制、信號(hào)量控制和異步編程,可以有效管理多線程環(huán)境下的數(shù)據(jù)庫訪問。關(guān)鍵在于平衡線程安全性和性能。

希望這篇文章能幫助您深入理解C#中SQLite的并發(fā)控制與多線程訪問。建議根據(jù)具體業(yè)務(wù)場景選擇最適合的并發(fā)策略。

責(zé)任編輯:武曉燕 來源: 技術(shù)老小子
相關(guān)推薦

2025-02-28 07:09:25

2024-10-18 16:58:26

2024-10-14 16:25:59

C#線程鎖代碼

2011-04-25 14:42:10

C#lock

2024-10-21 16:59:37

C#編程多線程

2009-08-17 16:56:51

C#多線程控制進(jìn)度條

2024-06-11 00:00:30

C#編程線程

2009-07-17 10:37:05

C#多線程

2009-08-21 11:31:59

異步和多線程的區(qū)別

2024-04-03 08:25:11

DictionaryC#字典類型

2009-08-12 18:04:44

編寫C#多線程

2009-08-26 18:13:55

C#多線程lock

2024-02-27 10:44:58

C#線程后端

2024-05-17 12:56:09

C#編程線程

2009-08-28 16:51:32

C#線程控制

2009-08-17 16:41:03

C#多線程控制

2009-08-17 16:29:56

C#多線程控制

2024-04-23 09:35:27

線程終止C#多線程編程

2009-08-28 16:43:57

C#多線程學(xué)習(xí)

2009-09-04 15:09:48

C#多線程啟動(dòng)Squa
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)