我将DataTable存储在ASP .NET Cache属性中。可以在该DataTable上执行的操作是:
我在显式处理该DataTable实例时添加了基本的读取器/编写器锁,但我不知道该解决方案是否存在任何其他线程安全问题。我猜想当网格控件在DataBinding中间时,某些东西可能会出错,而其他线程会删除行?如果是这样,我如何同步对该表的访问权限,以便在绑定网格控件时不进行删除方法调用?是否有任何事件组合,我可以把AcquireWriterLock& ReleaseWriterLock方法?
谢谢,帕维尔
答案 0 :(得分:2)
如果您通过数据绑定公开数据表,那就算了;你不能做那个线程安全的。即使你以某种方式(在自定义DataView
中)包装ITypedList
,这还不够 - 数据绑定会对数据做出假设,特别是IList
等 - 例如,它不会在迭代数据或在UI线程上添加行的中间以线程争用的方式随机更改长度。
通过事件在同一个线程上进行的更改<...>但不是交叉线程。
答案 1 :(得分:0)
正如人们在其他答案中提到的那样:
但是我真的需要缓存一个DataTable。原因:
但是,当用户对其看到的数据进行操作时,会对数据进行一些更改:
这就是我为该解决方案实现锁定的方式:
缓存数据存储在类似单身的包装器中:
public class AllocationQueue
{
private static object tableSyncRoot = new object();
这是修改缓存的DataTable的唯一代码:
internal void RemoveTaskRowFromAllocationQueue(Guid queueId, Guid taskId)
{
var allocationQueueEntry = GetAllocationQueueEntry(queueId);
var queueData = allocationQueueEntry.TaskIdIndexedView;
lock(tableSyncRoot)
{
int rowIndex = queueData.Find(new object[] { taskId });
queueData[rowIndex].Delete();
}
}
这是暴露数据绑定数据的唯一代码:
public DataTable GetAllocationQueue(Guid queueId, string filter)
{
var allocationQueueEntry = GetAllocationQueueEntry(queueId);
lock (tableSyncRoot)
{
var rows = allocationQueueEntry.Table.Select(filter);
if (rows.Length > 0)
{
return rows.CopyToDataTable<DataRow>();
}
}
return null;
}
线程安全&amp;就像一个魅力(我是对的吗:)。但这对我的要求非常具体。
答案 2 :(得分:0)
这是一种以线程安全的方式添加行的简单方法。其中 dt = 我的 DataTable 和 dr = 我的 DataRow
lock (dt.Rows.SyncRoot)
{
dt.Rows.Add(dr);
}