Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Kelas ini mengotomatiskan mengambil kunci untuk menyinkronkan akses ke objek dari beberapa utas. Ketika dibangun, ia memperoleh kunci dan ketika dihancurkan, ia melepaskan kunci.
Sintaks
ref class lock;
Keterangan
lock hanya tersedia untuk objek CLR dan hanya dapat digunakan dalam kode CLR.
Secara internal, kelas kunci menggunakan Monitor untuk menyinkronkan akses. Untuk informasi selengkapnya, lihat artikel yang dirujuk.
Anggota
Konstruktor Publik
| Nama | Deskripsi |
|---|---|
| lock::lock | Membangun lock objek, secara opsional menunggu untuk memperoleh kunci selamanya, untuk jumlah waktu tertentu, atau tidak sama sekali. |
| lock::~lock | lock Merusak objek. |
Metode Publik
| Nama | Deskripsi |
|---|---|
| lock::acquire | Memperoleh kunci pada objek, secara opsional menunggu untuk memperoleh kunci selamanya, untuk jumlah waktu tertentu, atau tidak sama sekali. |
| lock::is_locked | Menunjukkan apakah kunci sedang ditahan. |
| lock::release | Melepaskan kunci. |
| lock::try_acquire | Memperoleh kunci pada objek, menunggu jumlah waktu tertentu dan mengembalikan bool untuk melaporkan keberhasilan akuisisi alih-alih melemparkan pengecualian. |
Operator publik
| Nama | Deskripsi |
|---|---|
| lock::operator bool | Operator untuk menggunakan lock dalam ekspresi bersyarah. |
| lock::operator== | Operator kesetaraan. |
| lock::operator!= | Operator ketidaksamaan. |
Persyaratan
File header<msclr\lock.h>
Namespace msclr
lock::lock
Membangun lock objek, secara opsional menunggu untuk memperoleh kunci selamanya, untuk jumlah waktu tertentu, atau tidak sama sekali.
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
);
Parameter
_benda
Objek yang akan dikunci.
_Timeout
Nilai waktu habis dalam milidetik atau sebagai TimeSpan.
Pengecualian
ApplicationException Melempar jika akuisisi kunci tidak terjadi sebelum waktu habis.
Keterangan
Tiga bentuk pertama konstruktor mencoba memperoleh kunci dalam _object periode batas waktu yang ditentukan (atau Infinite jika tidak ada yang ditentukan).
Bentuk keempat konstruktor tidak memperoleh kunci pada _object. lock_later adalah anggota enum lock_when. Gunakan lock::acquire atau lock::try_acquire untuk memperoleh kunci dalam kasus ini.
Kunci akan secara otomatis dilepaskan ketika destruktor dipanggil.
_object tidak boleh ReaderWriterLock. Jika ya, kesalahan pengkompilasi akan dihasilkan.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada. Aplikasi utama kemudian menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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
lock Merusak objek.
~lock();
Keterangan
Destruktor memanggil lock::release.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada. Aplikasi utama kemudian menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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
Memperoleh kunci pada objek, secara opsional menunggu untuk memperoleh kunci selamanya, untuk jumlah waktu tertentu, atau tidak sama sekali.
void acquire();
void acquire(
int _timeout
);
void acquire(
System::TimeSpan _timeout
);
Parameter
_Timeout
Nilai batas waktu dalam milidetik atau sebagai TimeSpan.
Pengecualian
ApplicationException Melempar jika akuisisi kunci tidak terjadi sebelum waktu habis.
Keterangan
Jika nilai batas waktu tidak disediakan, batas waktu defaultnya adalah Infinite.
Jika kunci telah diperoleh, fungsi ini tidak melakukan apa pun.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada. Aplikasi utama kemudian menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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
Menunjukkan apakah kunci sedang ditahan.
bool is_locked();
Nilai hasil
true jika kunci ditahan, false jika tidak.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada, dan menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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 bool
Operator untuk menggunakan lock dalam ekspresi bersyarah.
operator bool();
Nilai hasil
true jika kunci ditahan, false jika tidak.
Keterangan
Operator ini benar-benar mengonversi yang _detail_class::_safe_bool lebih aman daripada bool karena tidak dapat dikonversi ke jenis integral.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada. Aplikasi utama menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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
Melepaskan kunci.
void release();
Keterangan
Jika tidak ada kunci yang ditahan, release tidak melakukan apa-apa.
Anda tidak perlu memanggil fungsi ini secara eksplisit. lock Ketika objek keluar dari cakupan, destruktornya memanggil release.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada. Aplikasi utama kemudian menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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
Memperoleh kunci pada objek, menunggu jumlah waktu tertentu dan mengembalikan bool untuk melaporkan keberhasilan akuisisi alih-alih melemparkan pengecualian.
bool try_acquire(
int _timeout_ms
);
bool try_acquire(
System::TimeSpan _timeout
);
Parameter
_Timeout
Nilai batas waktu dalam milidetik atau sebagai TimeSpan.
Nilai hasil
true jika kunci diperoleh, false jika tidak.
Keterangan
Jika kunci telah diperoleh, fungsi ini tidak melakukan apa pun.
Contoh
Contoh ini menggunakan satu instans kelas di beberapa utas. Kelas menggunakan kunci pada dirinya sendiri untuk memastikan bahwa akses ke data internalnya konsisten untuk setiap utas. Utas aplikasi utama menggunakan kunci pada instans kelas yang sama untuk memeriksa secara berkala untuk melihat apakah ada utas pekerja yang masih ada. Aplikasi utama kemudian menunggu untuk keluar sampai semua utas pekerja menyelesaikan tugas mereka.
// 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 kesetaraan.
template<class T> bool operator==(
T t
);
Parameter
t
Objek yang akan dibandingkan untuk kesetaraan.
Nilai hasil
Mengembalikan true jika t sama dengan objek kunci, false jika tidak.
Contoh
// 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 ketidaksamaan.
template<class T> bool operator!=(
T t
);
Parameter
t
Objek yang akan dibandingkan dengan ketidaksamaan.
Nilai hasil
Mengembalikan true jika t berbeda dari objek kunci, false jika tidak.
Contoh
// 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!