Klasa lock
Ta klasa automatyzuje pobieranie blokady na potrzeby synchronizowania dostępu do obiektu z kilku wątków. Po skonstruowaniu uzyskuje blokadę i po jej zniszczeniu zwalnia blokadę.
Składnia
ref class lock;
Uwagi
lock
jest dostępny tylko dla obiektów CLR i może być używany tylko w kodzie CLR.
Wewnętrznie klasa lock używa Monitor metody do synchronizowania dostępu. Aby uzyskać więcej informacji, zobacz artykuł, do których się odwołujesz.
Członkowie
Konstruktory publiczne
Nazwa/nazwisko | opis |
---|---|
lock::lock | lock Tworzy obiekt, opcjonalnie czekający na uzyskanie blokady na zawsze, przez określony czas lub w ogóle nie. |
lock::~lock | Destrukuje lock obiekt. |
Metody publiczne
Nazwa/nazwisko | opis |
---|---|
lock::acquire | Uzyskuje blokadę obiektu, opcjonalnie czekając na uzyskanie blokady na zawsze, przez określony czas lub w ogóle nie. |
lock::is_locked | Wskazuje, czy blokada jest przechowywana. |
lock::release | Zwalnia blokadę. |
lock::try_acquire | Uzyskuje blokadę obiektu, czekając na określony czas i zwracając element , bool aby zgłosić powodzenie pozyskiwania, zamiast zgłaszać wyjątek. |
Operatory publiczne
Nazwa/nazwisko | opis |
---|---|
lock::operator, wartość logiczna | Operator do użycia lock w wyrażeniu warunkowym. |
lock::operator== | Operator równości. |
lock::operator!= | Operator nierówności. |
Wymagania
Plik<nagłówka msclr\lock.h>
Przestrzeń nazw msclr
lock::lock
lock
Tworzy obiekt, opcjonalnie czekający na uzyskanie blokady na zawsze, przez określony czas lub w ogóle nie.
template<class T> lock(
T ^ _object
);
template<class T> lock(
T ^ _object,
int _timeout
);
template<class T> lock(
T ^ _object,
System::TimeSpan _timeout
);
template<class T> lock(
T ^ _object,
lock_later
);
Parametry
_Obiektu
Obiekt, który ma być zablokowany.
_Limit czasu
Wartość limitu czasu w milisekundach lub jako TimeSpan.
Wyjątki
Zgłasza błąd, jeśli pozyskiwanie ApplicationException blokady nie występuje przed przekroczeniem limitu czasu.
Uwagi
Pierwsze trzy formy konstruktora próbują uzyskać blokadę w _object
określonym przedziale czasu (lub Infinite jeśli nie określono żadnego).
Czwarta forma konstruktora nie uzyskuje blokady na ._object
lock_later
jest członkiem wyliczenia lock_when. Użyj polecenia lock::acquire or lock::try_acquire , aby uzyskać blokadę w tym przypadku.
Blokada zostanie automatycznie zwolniona po wywołaniu destruktora.
_object
nie może być .ReaderWriterLock Jeśli tak jest, zostanie wyświetlony błąd kompilatora.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy istnieją jakieś wątki robocze. Następnie główna aplikacja czeka na zakończenie działania, aż wszystkie wątki robocze zakończą swoje zadania.
// msl_lock_lock.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::~lock
Destrukuje lock
obiekt.
~lock();
Uwagi
Destruktor wywołuje funkcję lock::release.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy istnieją jakieś wątki robocze. Następnie główna aplikacja czeka na zakończenie działania, aż wszystkie wątki robocze zakończą swoje zadania.
// msl_lock_dtor.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::acquire
Uzyskuje blokadę obiektu, opcjonalnie czekając na uzyskanie blokady na zawsze, przez określony czas lub w ogóle nie.
void acquire();
void acquire(
int _timeout
);
void acquire(
System::TimeSpan _timeout
);
Parametry
_Limit czasu
Wartość limitu czasu w milisekundach lub jako TimeSpan.
Wyjątki
Zgłasza błąd, jeśli pozyskiwanie ApplicationException blokady nie występuje przed przekroczeniem limitu czasu.
Uwagi
Jeśli wartość limitu czasu nie jest podana, domyślnym limitem czasu jest Infinite.
Jeśli blokada została już uzyskana, ta funkcja nic nie robi.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy istnieją jakieś wątki robocze. Następnie główna aplikacja czeka na zakończenie działania, aż wszystkie wątki robocze zakończą swoje zadania.
// msl_lock_acquire.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::is_locked
Wskazuje, czy blokada jest przechowywana.
bool is_locked();
Wartość zwracana
true
jeśli blokada jest przechowywana, false
w przeciwnym razie.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy jakiekolwiek wątki robocze nadal istnieją, i czeka na zakończenie, aż wszystkie wątki robocze zakończyły swoje zadania.
// msl_lock_is_locked.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
l.try_acquire(50); // try to acquire lock, don't throw an exception if can't
if (l.is_locked()) { // check if we got the lock
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::operator, wartość logiczna
Operator do użycia lock
w wyrażeniu warunkowym.
operator bool();
Wartość zwracana
true
jeśli blokada jest przechowywana, false
w przeciwnym razie.
Uwagi
Ten operator faktycznie konwertuje na element, który _detail_class::_safe_bool
jest bezpieczniejszy, ponieważ bool
nie można go przekonwertować na typ całkowity.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy istnieją jakieś wątki robocze. Główna aplikacja czeka na zakończenie działania, aż wszystkie wątki robocze zakończą swoje zadania.
// msl_lock_op_bool.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
l.try_acquire(50); // try to acquire lock, don't throw an exception if can't
if (l) { // use bool operator to check for lock
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::release
Zwalnia blokadę.
void release();
Uwagi
Jeśli blokada nie jest utrzymywana, release
nic nie robi.
Nie musisz jawnie wywoływać tej funkcji. lock
Gdy obiekt wykracza poza zakres, jego destruktor wywołuje metodę release
.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy istnieją jakieś wątki robocze. Następnie główna aplikacja czeka na zakończenie działania, aż wszystkie wątki robocze zakończą swoje zadania.
// msl_lock_release.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::try_acquire
Uzyskuje blokadę obiektu, czekając na określony czas i zwracając element , bool
aby zgłosić powodzenie pozyskiwania, zamiast zgłaszać wyjątek.
bool try_acquire(
int _timeout_ms
);
bool try_acquire(
System::TimeSpan _timeout
);
Parametry
_Limit czasu
Wartość limitu czasu w milisekundach lub jako TimeSpan.
Wartość zwracana
true
w przypadku uzyskania blokady, false
w przeciwnym razie.
Uwagi
Jeśli blokada została już uzyskana, ta funkcja nic nie robi.
Przykład
W tym przykładzie użyto pojedynczego wystąpienia klasy w kilku wątkach. Klasa używa blokady samej siebie, aby upewnić się, że dostęp do danych wewnętrznych jest spójny dla każdego wątku. Główny wątek aplikacji używa blokady w tym samym wystąpieniu klasy, aby okresowo sprawdzać, czy istnieją jakieś wątki robocze. Następnie główna aplikacja czeka na zakończenie działania, aż wszystkie wątki robocze zakończą swoje zadania.
// msl_lock_try_acquire.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::operator==
Operator równości.
template<class T> bool operator==(
T t
);
Parametry
T
Obiekt do porównania pod kątem równości.
Wartość zwracana
Zwraca wartość true
, jeśli t
jest taka sama jak obiekt blokady, false
w przeciwnym razie.
Przykład
// msl_lock_op_eq.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
int main () {
Object^ o1 = gcnew Object;
lock l1(o1);
if (l1 == o1) {
Console::WriteLine("Equal!");
}
}
Equal!
lock::operator!=
Operator nierówności.
template<class T> bool operator!=(
T t
);
Parametry
T
Obiekt do porównania pod kątem nierówności.
Wartość zwracana
Zwraca wartość true
, jeśli t
różni się od obiektu blokady, false
w przeciwnym razie.
Przykład
// msl_lock_op_ineq.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
int main () {
Object^ o1 = gcnew Object;
Object^ o2 = gcnew Object;
lock l1(o1);
if (l1 != o2) {
Console::WriteLine("Inequal!");
}
}
Inequal!
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla