2016-11-22 7 views
0

Мы интегрируем библиотеку HDF5 в наше приложение .NET.C# .net HDF5 Проблема с Nunit?

Поскольку библиотека HDF5 не является потокобезопасной, мы инкапсулировали ее с помощью функции lock(). Один поток нашей программы работает в одном и эксклюзивном файле .h5.

Некоторые вычисления выполняются параллельно. Для параллельной части мы используем:

  • темы
  • Parallel.ForEach()

из:

  • System.Threading
  • System.Threading.Tasks.

Все работает файл execpt, когда мы выполняем несколько модульных тестов с NUnit v3.2.1 с резьбой, Parallel.ForEach, с одним экземпляром каждого на одном .h5 файла, конечные значения (как они читать и писать несколько раз) внутри нашего файла .h5 неверны (они верны в противном случае).

Мы подозреваем, что библиотека HDF5 имеет проблему с комбинацией всех четырех (HDF5, NUnit, Threads, Parallel.foreach). У нас нет четкого представления о том, что происходит.

Инструменты: Visual Studio 2015 Pro, NUNit v3.2.1 и NUnit3TestAdapter v3.5.1.

Любые предложения?

Заранее спасибо.

Вот пример того, как мы пишем некоторые данные внутри нашего файла:

public void SetGroupAttribute(H5LocId hdf5Handle, string location, string attribute, int value) 
    { 
     lock (AccessLock) 
     { 
      // Retrieve the attribute to read 
      var attributeId = GetAttribute(hdf5Handle, location, attribute); 

      H5GroupId rootId = null; 
      if (attributeId != null) 
      { 
       // Remove the old attribute 
       rootId = H5G.open(hdf5Handle, location); 
       H5A.Delete(rootId, attribute); 
       H5G.close(rootId); 
      } 

      // Create and set the new attribute value 
      H5DataSpaceId spaceId = H5S.create(H5S.H5SClass.SCALAR); 
      var attributeType = H5T.copy(H5T.H5Type.NATIVE_INT); 

      rootId = H5G.open(hdf5Handle, location); 
      attributeId = H5A.create(rootId, attribute, attributeType, spaceId); 
      H5G.close(rootId); 

      // Set the attribute value 
      int[] dims = new int[1]; 
      dims[0] = value; 
      H5A.write<int>(attributeId, attributeType, new H5Array<int>(dims)); 
      H5A.close(attributeId); 
     } 
    } 
+0

В чем смысл использования 'Parallel', если вы используете блокировки? Кроме того, блокировка не делает что-то потокобезопасным по магии. Является ли 'AcessLock' статическим или экземпляром поля? Кто-нибудь еще использует ручку? –

+0

I * не будет * использовать блокировку для защиты такого ресурса. Я бы использовал ActionBlock ] (https://msdn.microsoft.com/en-us/library/hh194684 (v = vs.110) .aspx), чтобы отправлять сообщения блоку, который выполняет изменения с использованием одной задачи. –

+0

Параллель используется для наших разных вычислений (поскольку мы одновременно вычисляем несколько данных). AccessLock - это поле экземпляра (объект) внутри одноэлементного (где используются методы .h5 IO). Я проверю ActionBlock. Благодаря! – Fabi1

ответ

0

До сих пор я решил проблему, сохраняя ту же конфигурацию (NUnit, нитки и Parallel.ForEach), выполнив следующие действия каждый раз, когда Я редактировать файл hdf5:

  1. Открыть файл
  2. операции Do IO
  3. Закройте файл
  4. Повторное открытие файла в режиме чтения/записи (H5F.OpenMode.ACC_RDWR)
  5. Закройте файл

Каждая операция крепится с помощью замка внутри нашего HDF5 хелперов одноплодной. Это работает, поскольку один поток работает над одним файлом .h5 за раз.

Кажется, что библиотека HDF5 выполняет операции async, когда вы закрываете файл .h5, так как на этом этапе данные помещаются внутри файла.

В документации не ясно.

Я взял эту идею из этой темы: HDF5 Example code

hdf5 документацию о H5F.Close: http://hdf5.net/api/M_HDF5DotNet_H5F_close_1_4829088c.aspx

0

проблема теперь решена.

Одна из наших операций забыли закрыть элемент набора данных из файла HDF5, в результате чего H5F.Close окажется неэффективным.

Симптомы:

  • файла все еще используется библиотекой
  • новые данные не смывали в файл

Решение:

  • проверка каждый объект из библиотеку HDF5, которую нужно закрыть, когда она используется.

 Смежные вопросы

  • Нет связанных вопросов^_^