DLL Funktion in anderen Thread schieben



  • Hallo.

    Ich habe eine recht umfangreiche Funktion in C/C++ geschrieben und in eine DLL gepackt. Diese Funktion liest eine Datei aus, reserviert Speicher und legt den Inhalt der Datei dort ab, splittet die Daten in ein Array und gibt das zurück.

    Die Funktion wird von meiner C#-GUI ausgeführt. Da die Datenmenge sehr groß ist, friert dabei meine GUI immer für mehrere Minuten ein. Ich wollte daher diese Arbeit einem eigenen Thread übergeben. Dazu liefert Google reichlich Beispiele, die jedoch alle nicht funktionieren, da ich unsafe arbeite. Das kann ich sogar verstehen. Ich übergebe der Funktion den Zeiger auf ein unsigned int, wo die DLL-Funktion die Anzahl der Array Einträge ablegt - diese Adresse könnte sich in der Zeit, in welcher der Thread ausgeführt wird wohl ändern und genau hier meckert auch mein Compiler mit dem Hinweis:
    https://msdn.microsoft.com/en-us/library/32f285cy(v=vs.90).aspx

    Die Funktion in der DLL:

    extern "C" __declspec(dllexport) TMesh** MSH2MeshStack(char* filename, unsigned int* fnMesh, unsigned int Output)
    

    Dabei ist TMesh eine eigene Struktur, welche die Daten enthält und fnMesh ist die besagte unsigned int Variable.

    In C# habe ich das wie folgt ausgeführt:

    public static int ReadMesh3DMSHFCT(string FileName = "Read File Name")
            {
                Struct_cs.TMesh** fppMesh = null;
                Struct_cs.TMesh* fpMesh = null;
                UInt16 AddedMeshNumber = 0;
                UInt16 OldMeshStackSize = (UInt16)GlobalVariables.MeshStack.Count();
                OpenFileDialog OPF = null;
    
                if (FileName == "Read File Name")
                {
                    OPF = new OpenFileDialog();
    
                    OPF.InitialDirectory = Application.StartupPath;
                    OPF.Filter = "Fluent mesh files (*.msh)|*.msh|All files (*.*)|*.*";
                    OPF.FilterIndex = 1;
                    OPF.RestoreDirectory = true;
    
                    if (OPF.ShowDialog() == DialogResult.OK)
                    {
                        try
                        {
                            FileName = OPF.FileName;
                        }
                        catch (Exception ex)
                        {
                            Output.LogOut("Error extracting filenam string. Original error: " + ex.Message);
                            return 1;
                        }
                    }
                }
    
                new Thread(() =>
                {
                    Thread.CurrentThread.IsBackground = true;
                    fppMesh = (Struct_cs.TMesh**)ReadMeshDLLInterface.MSH2MeshStack(FileName, &AddedMeshNumber, 1);
                }).Start();
    
                for (int i = OldMeshStackSize; i < OldMeshStackSize + AddedMeshNumber; i++)
                {
                    GlobalVariables.MeshStack.Add(new CMesh((UInt16)i));
                }
    
                ArcRotation.RenderAll();
                ArcRotation.Refresh3DWindow();
    
                return 0;
            }
    

    Wie kann ich diesen Fehler umgehen?



  • In dem du den Thread außerhalb der Methode startest?

    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(Object state)
    {
       int result = ReadMesh3DMSHFCT(@"C:\temp.txt");
       // hier event werfen damit das Ergebnis an die GUI weitergegeben werden kann
    }));
    

    Zumal du dir das Thema Threading allgemein ansehen solltest. - Dein Code kann nämlich nur Fehler generieren.

    Du startest deinen Thread, arbeitest im nächsten Zug aber schon mit dem ergebnis, obwohl der Thread noch nicht fertig ist.


Log in to reply