HDFGroup / HDF.PInvoke

Raw HDF5 Power for .NET
http://www.hdfgroup.org/HDF5
Other
80 stars 29 forks source link

BUG REPORT about multithreading with multiple File #146

Closed BrightstarKing closed 5 years ago

BrightstarKing commented 6 years ago

I met a problem when I try to use 2 threads with C# Task.Run create and operate 2 different independent HDF5 file, it throw some Exception like "Try to read or write protected memory.This usually indicates that other memory is damaged", sometimes with H5F.create and sometimes with H5G.create, just random, sometimes even no problems, I don't know if this is a BUG or I made some mistakes that I didn't notice, please help me and thanks!

Here is the C# 4.6.1 framework x64 Console Program:

using System.IO; using System; using System.Threading.Tasks; using HDF.PInvoke;

namespace ConsoleTest { class Program { static void Main(string[] args) { var doer = new H5FileAndGroupTests(); doer.init(); Console.ReadKey(false); } }

public class H5FileAndGroupTests
{
    public string filename1 = @"D:/Run/testH51.h5";
    public string filename2 = @"D:/Run/testH52.h5";
    public string group1Name = "myGroup1";
    public string group2Name = "myGroup2";

    public void init()
    {
        asyncInitFile(filename1);
        asyncInitFile(filename2);
    }

    private async void asyncInitFile(string filename)
    {
        await Task.Run(() => initFile(filename));
    }

    private void initFile(string filename)
    {
        File.Delete(filename);

        int myFileID = H5F.create(filename, H5F.ACC_EXCL);
        int myGroup1ID = H5G.create(myFileID, group1Name);
        int myGroup2ID = H5G.create(myFileID, group1Name);

        H5O.close(myGroup2ID);
        H5O.close(myGroup1ID);
        H5F.close(myFileID);
    }
}

}

BrightstarKing commented 6 years ago

I think I have found the problem: When I try to create some different HDF5 Files, the different URLs return the same int ID value, this may led to the problem that "Try to read or write protected memory"

here is the test result in Console: created D:/Run/001testH5.h5 ID = 16777216 created D:/Run/002testH5.h5 ID = 16777217 created D:/Run/004testH5h5 ID = 16777218 created D:/Run/003testH5.h5 ID = 16777219 created D:/Run/005testH5.h5 ID = 16777216 created D:/Run/006testH5.h5 ID = 16777216 created D:/Run/007testH5.h5 ID = 16777216 created D:/Run/008testH5.h5 ID = 16777216

Apollo3zehn commented 6 years ago

Are you using the thread safe version of the HDF5 dll? You can check it like:

uint isLibraryThreadSafe = 0;

H5.is_library_threadsafe(ref isLibraryThreadSafe);

if (isLibraryThreadSafe <= 0)
{
    throw new Exception("Library is not thread-safe!");
}
BrightstarKing commented 6 years ago

@Apollo3zehn Thanks for your help! I use HDF.PInvoke in C# nuget, version 1.8.20, but I can,t find the definiation of "H5.is_library_threadsafe(ref isLibraryThreadSafe)", which version do you use?

Apollo3zehn commented 6 years ago

I am using version 1.10.2 but if I create a new WPF Desktop project and install HDF.Pinvoke version 1.8.20 and use the following code, it works:

using HDF.PInvoke;
using System;
using System.Windows;

namespace WpfApp3
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            uint isLibraryThreadSafe = 0;

            H5.is_library_threadsafe(ref isLibraryThreadSafe);

            if (isLibraryThreadSafe <= 0)
            {
                throw new Exception("Library is not thread-safe!");
            }
        }
    }
}

The only error I get when executing the application, is that the HDF dll is not found but that is a different story and related to the fact that NuGet changed the way external libraries are linked.

BrightstarKing commented 5 years ago

@Apollo3zehn I followed your way, it works, and says "Library is not thread-safe", thank you very much! Do you know how to make it thread-safe?

Apollo3zehn commented 5 years ago

According to this Wiki, the libraries should be thread safe. But I had a similar issue caused by having separately installed HDF in my programs. So I had this HDF Installation with source code, tools and HDF libraries in my C drive AND the HDF PInvoke nuget package in my project. Because the HDF Installation is in the DLL search path, these non thread-safe dlls are loaded first and your HDF.PInvoke dlls are not used. Your only option I think is to remove the HDF Installation or at least modify your %PATH% variable and exclude the path to the HDF Installation. Keep in mind that there is more than one path variable, which are combined by Windows. I think there is a system and a user path variable.

BrightstarKing commented 5 years ago

@Apollo3zehn Yes you're right. I move the *.dll in ".../package/HDF.PInvoke.1.8.20.0/..." in my project to the bin file, and now it's thread safe. Thanks a lot!

Apollo3zehn commented 5 years ago

OK, thats another way so solve it 👍