You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

360 lines
9.7 KiB

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SunlightCentralizedControlManagement_SCCM_.UserClass
{
/// <summary>
/// 线程安全的 DataTable 管理器
/// 提供对 DataTable 的安全并发访问
/// </summary>
public class DataTableManager : IDisposable
{
private DataTable _dataTable;
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private bool _disposed = false;
#region 构造函数
public DataTableManager()
{
_dataTable = new DataTable();
}
public DataTableManager(DataTable dataTable)
{
_dataTable = dataTable ?? throw new ArgumentNullException(nameof(dataTable));
}
public DataTableManager(string tableName)
{
_dataTable = new DataTable(tableName);
}
#endregion
#region 基本操作
/// <summary>
/// 安全地添加列
/// </summary>
public void AddColumn(string columnName, Type dataType)
{
ExecuteWriteOperation(table =>
{
table.Columns.Add(columnName, dataType);
});
}
/// <summary>
/// 安全地添加行
/// </summary>
public void AddRow(params object[] values)
{
ExecuteWriteOperation(table =>
{
DataRow newRow = table.NewRow();
for (int i = 0; i < Math.Min(values.Length, table.Columns.Count); i++)
{
newRow[i] = values[i] ?? DBNull.Value;
}
table.Rows.Add(newRow);
});
}
/// <summary>
/// 安全地更新单元格值
/// </summary>
public bool UpdateCell(int rowIndex, string columnName, object value)
{
return ExecuteWriteOperation(table =>
{
if (IsValidRowIndex(table, rowIndex) && table.Columns.Contains(columnName))
{
table.Rows[rowIndex][columnName] = value ?? DBNull.Value;
return true;
}
return false;
});
}
/// <summary>
/// 安全地删除行
/// </summary>
public bool DeleteRow(int rowIndex)
{
return ExecuteWriteOperation(table =>
{
if (IsValidRowIndex(table, rowIndex))
{
table.Rows[rowIndex].Delete();
return true;
}
return false;
});
}
#endregion
#region 查询操作
/// <summary>
/// 安全地获取行
/// </summary>
public DataRow GetRow(int rowIndex)
{
return ExecuteReadOperation(table =>
{
return IsValidRowIndex(table, rowIndex) ? table.Rows[rowIndex] : null;
});
}
/// <summary>
/// 安全地查找行(使用筛选条件)
/// </summary>
public DataRow[] FindRows(string filterExpression)
{
return ExecuteReadOperation(table =>
{
try
{
return string.IsNullOrEmpty(filterExpression)
? table.Select()
: table.Select(filterExpression);
}
catch (EvaluateException)
{
return new DataRow[0];
}
});
}
/// <summary>
/// 安全地获取行数
/// </summary>
public int GetRowCount()
{
return ExecuteReadOperation(table => table.Rows.Count);
}
/// <summary>
/// 安全地检查行是否存在
/// </summary>
public bool RowExists(int rowIndex)
{
return ExecuteReadOperation(table => IsValidRowIndex(table, rowIndex));
}
#endregion
#region 批量操作
/// <summary>
/// 安全地批量添加行
/// </summary>
public void BulkAddRows(IEnumerable<object[]> rowsData)
{
ExecuteWriteOperation(table =>
{
foreach (var rowData in rowsData)
{
DataRow newRow = table.NewRow();
for (int i = 0; i < Math.Min(rowData.Length, table.Columns.Count); i++)
{
newRow[i] = rowData[i] ?? DBNull.Value;
}
table.Rows.Add(newRow);
}
});
}
/// <summary>
/// 安全地清空所有数据
/// </summary>
public void Clear()
{
ExecuteWriteOperation(table =>
{
table.Clear();
});
}
#endregion
#region 数据导出
/// <summary>
/// 获取数据快照(线程安全的副本)
/// </summary>
public DataTable GetSnapshot()
{
return ExecuteReadOperation(table =>
{
return table.Copy(); // 创建数据的独立副本
});
}
/// <summary>
/// 获取只读视图
/// </summary>
public DataView GetReadOnlyView()
{
return ExecuteReadOperation(table =>
{
return new DataView(table) { AllowEdit = false };
});
}
/// <summary>
/// 导出到新 DataTable(包含结构)
/// </summary>
public DataTable ExportToDataTable()
{
return ExecuteReadOperation(table =>
{
DataTable exported = table.Clone();
exported.Merge(table, false, MissingSchemaAction.Add);
return exported;
});
}
#endregion
#region 锁操作核心
/// <summary>
/// 执行读取操作(共享锁)
/// </summary>
private T ExecuteReadOperation<T>(Func<DataTable, T> operation)
{
_lock.EnterReadLock();
try
{
return operation(_dataTable);
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 执行写入操作(独占锁)
/// </summary>
private void ExecuteWriteOperation(Action<DataTable> operation)
{
_lock.EnterWriteLock();
try
{
operation(_dataTable);
_dataTable.AcceptChanges();
}
finally
{
_lock.ExitWriteLock();
}
}
private T ExecuteWriteOperation<T>(Func<DataTable, T> operation)
{
_lock.EnterWriteLock();
try
{
var result = operation(_dataTable);
_dataTable.AcceptChanges();
return result;
}
finally
{
_lock.ExitWriteLock();
}
}
private bool IsValidRowIndex(DataTable table, int rowIndex)
{
return rowIndex >= 0 && rowIndex < table.Rows.Count;
}
#endregion
#region 高级功能
/// <summary>
/// 带超时的安全操作
/// </summary>
public bool TryUpdateCell(int rowIndex, string columnName, object value, int timeoutMs = 5000)
{
if (_lock.TryEnterWriteLock(timeoutMs))
{
try
{
if (IsValidRowIndex(_dataTable, rowIndex) && _dataTable.Columns.Contains(columnName))
{
_dataTable.Rows[rowIndex][columnName] = value ?? DBNull.Value;
_dataTable.AcceptChanges();
return true;
}
return false;
}
finally
{
_lock.ExitWriteLock();
}
}
return false;
}
/// <summary>
/// 执行事务性操作
/// </summary>
public void ExecuteTransaction(Action<DataTable> transaction)
{
_lock.EnterWriteLock();
try
{
// 开始事务
_dataTable.BeginLoadData();
try
{
transaction(_dataTable);
_dataTable.AcceptChanges();
}
catch
{
_dataTable.RejectChanges();
throw;
}
finally
{
_dataTable.EndLoadData();
}
}
finally
{
_lock.ExitWriteLock();
}
}
#endregion
#region 属性和清理
public string TableName
{
get => ExecuteReadOperation(table => table.TableName);
set => ExecuteWriteOperation(table => table.TableName = value);
}
public DataColumnCollection Columns
{
get => ExecuteReadOperation(table => table.Columns);
}
public void Dispose()
{
if (!_disposed)
{
_lock?.Dispose();
_dataTable?.Dispose();
_disposed = true;
}
GC.SuppressFinalize(this);
}
~DataTableManager()
{
Dispose();
}
#endregion
}
}