Параллельное выполнение метода с блокировкой .NET C # - PullRequest
0 голосов
/ 22 сентября 2018

У меня есть 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 голосов
/ 22 сентября 2018

Я лично согласился бы с ответом Кевинса

Однако, если вы хотите, чтобы эти резервные копии работали независимо (не дожидаясь окончания всех школ), в основном с вашим текущим шаблоном.Затем можно поиграть с такими идеями, как

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