.net C#中的线程安全DataTable

iih3973s  于 2023-05-08  发布在  .NET
关注(0)|答案(1)|浏览(322)

我有一个Timer,它每15分钟更新一次DataTable,我有十个线程在这个DataTable上搜索。如果我在阅读的时候锁定数据表,程序的速度会很慢,有没有办法只在写的时候锁定DataTable
我的代码:

//variable
private static readonly Object lockObj = new Object();
private static DataTable DT = new DataTable();

//start
Timer update_timer = new System.Timers.Timer(60000*15);
update_timer.Elapsed += new ElapsedEventHandler(updateDataTable);
updatetimer.Start();

Thread readThread = new Thread(new ThreadStart(() => searchDataTable(0) ));
readThread.Start();
...
Thread readThread10 = new Thread(new ThreadStart(() => searchDataTable(9) ));
readThread10.Start();

//function
private void updateDataTable(object source, ElapsedEventArgs e)
{
   lock (lockObj)
   {
     // read data from database and update DT
   }
}    

private void searchDataTable(int index)
{
  string tempItem="";
  while(ConcurrentQueueDictionary[index].TryDequeue(out tempItem))
  {
     lock (lockObj)
     {
        // search tempItem on DT
     }
   }
 }

我没有写完整的代码,以免太长。但重要的部分已经写好了。

y1aodyip

y1aodyip1#

一个解决方案是使用ReaderWriterLockSlim。这样,in writing mode the DataTable is locked。但是several threads can read from the DataTable at the same time on reading mode

//variable
private static readonly ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();
private static DataTable DT = new DataTable();

//start
Timer update_timer = new System.Timers.Timer(60000*15);
update_timer.Elapsed += new ElapsedEventHandler(updateDataTable);
updatetimer.Start();

Thread readThread = new Thread(new ThreadStart(() => searchDataTable(0) ));
readThread.Start();
...
Thread readThread10 = new Thread(new ThreadStart(() => searchDataTable(9) ));
readThread10.Start();

//function
private void updateDataTable(object source, ElapsedEventArgs e)
{
   lockObj.EnterWriteLock();
   try
   {
     // read data from database and update DT
   }
   finaly
   {
      lockObj.ExitWriteLock();
   }
}    

private void searchDataTable(int index)
{
  string tempItem="";
  while(ConcurrentQueueDictionary[index].TryDequeue(out tempItem))
  {
      lockObj.EnterReadLock();
        // search tempItem on DT
     lockObj.ExitReadLock();         
  }
}

ReaderWriterLockSlim
不管递归策略如何,任何时候都只能有一个线程处于写模式。当一个线程处于写模式时,其他线程不能以任何模式进入锁。任何时候都只能有一个线程处于可升级模式。任何数量的线程都可以处于读取模式,并且可以有一个线程处于可升级模式,而其他线程处于读取模式。

相关问题