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

时间:2018-09-22 08:55:38

标签: c# multithreading parallel-processing

我有一个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"));
         }
     }

      ...

  }

1 个答案:

答案 0 :(得分:3)

我个人会和凯文斯一起回答

但是,如果您希望这些备份独立运行(不必等待所有学校完成),并且大多数情况下使用您当前的模式。然后可以玩一些这样的想法

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);

      }
   }
}

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

此外,您可能只使用TryAddTryRemove而忽略了值

if (!_dict.TryAdd(ipAddress, false))
   return;

SchoolFunctions.Backup(ipAddress , row.Field<string>("Name"));

_dict.TryRemove(ipAddress,out _);