Skip to main content
 首页 » 编程设计

c#之带锁的并行方法执行 .NET C#

2024年02月25日32jackei

我有一个 xml 文件,其中包含所有带有 IP 地址的学校名称,我正尝试按计时器间隔备份每所学校(即 SchoolFunctions.Backup)。

问题是在某些情况下备份太慢,备份方法会在之前的备份仍在运行时再次启动......

如果 SchoolFunctions.Backup 仍在为该学校运行,我如何阻止它的执行?

using (DataTable schools = new DataTable { TableName = "Schools" }) 
{ 
     schools.ReadXml(AppSettings.Default.SettingsPath); 
     try 
     { 
         Parallel.ForEach(schools.AsEnumerable(), _opts, row => 
         { 
             SchoolFunctions.Backup(row.Field<string>("IPAddress"), row.Field<string>("Name")); 
         } 
     } 
 
      ... 
 
  } 

请您参考如下方法:

我个人会同意凯文斯的回答

但是,如果您希望这些备份独立工作(不必等待所有学校完成),则主要采用您当前的模式。然后可以玩一些像这样的想法

private ConcurrentDictionary<string,bool> _dict = new ConcurrentDictionary<string,bool>(); 
 
... 
 
using (DataTable schools = new DataTable { TableName = "Schools" }) 
{ 
   schools.ReadXml(AppSettings.Default.SettingsPath); 
 
   try 
   { 
      Parallel.ForEach(schools.AsEnumerable(), _opts, row => 
      { 
         var ipAddress = row.Field<string>("IPAddress"); 
 
         // check if there is an ip registered and if its processing 
         if (_dict.TryGetValue(ipAddress, out processing) && processing) 
            return; 
 
          // its not processing ,so update it 
         _dict.AddOrUpdate(ipAddress, true, (s, b) => true); 
 
         SchoolFunctions.Backup(ipAddress , row.Field<string>("Name")); 
 
         // when we are done update processing to false 
         _dict.AddOrUpdate(ipAddress, false, (s, b) => false); 
 
      } 
   } 
} 

注意,有很多方法可以做到这一点,但是这看起来很有希望。也没有测试

此外,您可能只使用 TryAdd 和 TryRemove 并忽略该值

if (!_dict.TryAdd(ipAddress, false)) 
   return; 
 
SchoolFunctions.Backup(ipAddress , row.Field<string>("Name")); 
 
_dict.TryRemove(ipAddress,out _);