Laden...

Wie kann ich Thread-Safe auf eine gemeinsame Dll zugreifen?

Erstellt von PierreDole vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.147 Views
P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren
Wie kann ich Thread-Safe auf eine gemeinsame Dll zugreifen?

Moin, mein Programm crasht, wenn ich mit zwei Threads auf eine DLL zugreife und ich kriege das nicht hingebogen. Ist alles noch trail & error, was ich hier mache. 😃 Es handelt sich hierbei um ein Wrapper, der ursprünglich in Java geschrieben und später von jemandem in C# umgeschrieben wurde.


[MethodImpl(MethodImplOptions.Synchronized)]
        private int GetInt(string command)
        {
            UODLL.SetTop(UOHandle, 0);
            UODLL.PushStrVal(UOHandle, "Get");
            UODLL.PushStrVal(UOHandle, command);
            var result = UODLL.Execute(UOHandle);
            if (result == 0)
                return UODLL.GetInteger(UOHandle, 1);
            else
                return 0;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        private void SetInt(string command, int value)
        {
            UODLL.SetTop(UOHandle, 0);
            UODLL.PushStrVal(UOHandle, "Set");
            UODLL.PushStrVal(UOHandle, command);
            UODLL.PushInteger(UOHandle, value);
            UODLL.Execute(UOHandle);
        }

So sehen die Methoden aus. [MethodImpl(MethodImplOptions.Synchronized)] kam von mir, bewirkt leider nichts. Kracht nach wie vor an selber Stelle.

Im Java-Original sieht das so aus:

    public synchronized  void pushInteger(int value) {
        game.PushInteger(handle, value);
    }

    public synchronized  int getInteger(int index) {
        return game.GetInteger(handle, index);
    }

Was ist C#'s Gegenstück zu Javas "synchronized"?

16.806 Beiträge seit 2008
vor 3 Jahren

Was ist C#'s Gegenstück zu Javas "synchronized"? Google-Suche nach java synchronized c#

P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren

Hab ich doch. 😄 Aber wie gesagt, [MethodImpl(MethodImplOptions.Synchronized)] funktioniert nicht. Und lock(GetInt) kommt nicht mal an den Compiler heran, wird rot unterstrichen.

16.806 Beiträge seit 2008
vor 3 Jahren

Deine Frage war, was das Gegenstück zu synchronized sei; diese hab ich beantwortet.

lock(GetInt)

Mit Try und Error, wie Du selbst es beschreibst wirste halt auch nicht weit kommen.
Schau in die Doku von lock(), dann siehst mit Code Beispiel wie es funktioniert - und bekommst nebenbei erklärt, wieso lock(GetInt) eben nicht gehen kann und unterstrichen wird.

[MethodImpl(MethodImplOptions.Synchronized)] selbst funktioniert sehr wohl; wenn es in Deinem Fall nicht funktioniert, dann liegt es eventuell an etwas anderem.

MethodImplOptions.Synchronized bewegt den Compiler auch nur dazu, ein lock() um eine gesamte Methode zu setzen.

[MethodImpl(MethodImplOptions.Synchronized)]
public void MethodImpl()
{
   // Do anything
}

>>>

public void Method()
{
    lock(this)
    {
        MethodImpl();
    }
}
P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren

Nun gehts.

private int GetInt(string command)
        {
            lock(this)
            {
                UODLL.SetTop(UOHandle, 0);
                UODLL.PushStrVal(UOHandle, "Get");
                UODLL.PushStrVal(UOHandle, command);
                var result = UODLL.Execute(UOHandle);
                if(result == 0)
                    return UODLL.GetInteger(UOHandle, 1);
                else
                    return 0;
            }
        }

Frage mich aber, warum [MethodImpl(MethodImplOptions.Synchronized)] bei mir nicht funktioniert hat. Fände diese Lösung eleganter.

T
2.219 Beiträge seit 2008
vor 3 Jahren

Am einfachsten dann mit static readonly object.
Readonly damit niemand die Instanz überschreibt und dann dein Lock nicht mehr greift.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.806 Beiträge seit 2008
vor 3 Jahren

Das kann man so pauschal nicht sagen, T-Virus.

Ein statisches Objekt als Lock-Objekt gilt dann für alle Instanten der jeweiligen Klassen - das ist aber nicht immer gewünscht; oder sinnvoll.
Sofern die Klasse selbst bereits ein Singleton darstellt (zB über Dependency Injection) brauchst Du kein statisches Lockobjekt.

Letzten Endes kommt es auf die gesamte Verwendung der Anwendung (und DLL) an.