PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [MFC -> .NET] gibt's da so was wie CSingleLock()?


Gast
2006-07-17, 16:14:25
Hi Leute,

ich arbeite daran, ein multithreaded MFC-Programm nach .NET zu portieren. Das Programm enthält jede menge critical Sections. In der MFC gab's dafür die Klassen CCriticalSection und CSingleLock, CCriticalSection repräsentierte das Synchronisationsobjekt, CSingleLock bot die Methoden Lock() und Unlock() zum Eröffnen und Verlassen der critical section an:

CCriticalSection cs;

// enter critical section
CSingleLock sl(&cs);
sl.Lock();
//...
// release critical section
sl.Unlock();

Der große Vorteil: man mußte Unlock() nicht notwendigerweise manuell aufrufen, die critical section wurde automatisch freigegeben, wenn die CSingleLock-Instanz gelöscht wurde, z.B. bei Verlassen des Blocks in dem sie erstellt wurde:

//...
{
// enter critical section
CSingleLock sl(&cs);
sl.Lock();
//...
// automated release of cs at end of code block
}


In .NET tritt an die Stelle von CCriticalSection die Klasse System:Threading::Mutex (es gab auch in der MFC eine Klasse CMutex, das Mutex aus .NET umfaßt offenbar beides, Mutex und critical section), die zum Eröffnen und Verlassen der critical section die Methoden WaitOne() und ReleaseMutex() zur Verfügung stellt. Obiges Codebeispiel sieht dann so aus:

System::Threading::Mutex mutex;

// enter critical section
mutex.WaitOne();
//...
// release critical section
mutex.ReleaseMutex();


Was ich jetzt gerne wissen würde wäre, ob auch .NET den Komfort einer Klasse wie CSingleLock anbietet, bei deren Deintanziieren die critical section automatisch freigegeben wird? Oder muß man das da wieder von Hand erledigen?

del_4901
2006-07-17, 16:16:53
Wenn das ned gibt kannste dir das ganz schnell selber programmiern, einfach in den Destruktor packen und gut is.

Trap
2006-07-17, 16:34:27
Es gibt keine Destruktoren in .NET, es gibt eine gemeine Falle die so ähnlich aussieht wie ein Destruktor, sich aber völlig anders verhält.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrflockstatement.asp dürfte das passenste Gegenstück für CSingleLock sein.

Macht allerdings nicht das gleiche, für das gleiche Verhalten muss man sich wohl tatsächlich selbst was schreiben, dann an http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconFinalizeDispose.asp halten, damit es auch funktioniert. Außerdem muss man als Nutzer der Klasse dann sowas schreiben:
using(new MySingleLock(mutex)) {
//cs here
}
um zu garantieren, dass Dispose auch wirklich sofort aufgerufen wird.

Gast
2006-07-17, 17:06:05
Trap[/POST]']Es gibt keine Destruktoren in .NET, es gibt eine gemeine Falle die so ähnlich aussieht wie ein Destruktor, sich aber völlig anders verhält.dieses Gerücht habe ich schon einmal gehört. Und derjenige, der es mir erzählt hat, meinte damit offenbar nichts anderes als daß es kein delete gibt. Mein Gesprächspartner ging wohl davon aus, daß Destruktoren nur dann relevant sind, wenn sie entweder von delete aufgerufen werden, oder selbst delete aufrufen.

Nun, ein delete gibt es noch - es ist nur nicht auf managed Klassen anwendbar. Auf unmanaged Klassen dagegen sehr wohl - und die sind soweit ich das festellen konnte mit gewissen Einschränkungen auch benutzbar.

Etwas, das sich wie Destruktoren verhält, gibt es offenbar auch, sogar bei managed Klassen, sofern diese nicht dynamisch mit gcnew, sondern automatisch instanziiert wurden. Das Schema sieht so aus:

automatisch dynamisch(new/gcnew)
unmanaged ja ja
managed ja nein

Trap
2006-07-17, 17:24:30
Gast[/POST]']
Etwas, das sich wie Destruktoren verhält, gibt es offenbar auch, sogar bei managed Klassen, sofern diese nicht dynamisch mit gcnew, sondern automatisch instanziiert wurden.
Wie sieht sowas im Code aus? Genauer: Wie erzeugt man Objekte einer selbstdefinierten class oder eines selbstdefiniertem struct ohne new zu benutzen?

Gast
2006-07-17, 17:43:50
Trap[/POST]']Wie sieht sowas im Code aus? Genauer: Wie erzeugt man Objekte einer selbstdefinierten class oder eines selbstdefiniertem struct ohne new zu benutzen?vielleicht so?

class wurst
{
//...
};

//...
wurst salami;

Trap
2006-07-17, 17:52:25
Ah, hatte nicht an die managed C++-Variante gedacht.

Elemental
2006-07-18, 10:58:31
Wieso sollte hier eine Instanz von wurst angelegt werden? Ist die Variable salami hier nicht null?

Trap
2006-07-18, 11:14:14
Elemental[/POST]']Wieso sollte hier eine Instanz von wurst angelegt werden? Ist die Variable salami hier nicht null?
Das ist C++, nicht C# oder Java, da kann salami garnicht 0/null sein.

Elemental
2006-07-18, 11:40:34
Stimmt, is ja kein Pointer. Ich sollt mal wieder mehr mit C++ arbeiten... Ne, ich glaub doch nicht... ;)