Ok I think I have found the problem.
for those who want to know:
Try run a simple code below (C# windows App):
public partial class Form1 : Form
{
private const int ObjectCount = 1000;
private const int ThreadCount = 50;
System.Threading.Thread[] _Threads;
Test[] _TestS=null;
static bool bLoop = false;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
bLoop = true;
_Threads = new System.Threading.Thread[ThreadCount];
if (_TestS != null)
{
for (int i = 0; i < ObjectCount; i++)
{
_TestS[i].Dispose();
}
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
_TestS = new Test[ObjectCount];
for (int i = 0; i < ObjectCount; i++)
{
_TestS[i] = new Test();
}
for (int i = 0; i < ThreadCount; i++)
{
_Threads[i] = new System.Threading.Thread(Do);
_Threads[i].IsBackground = true;
}
for (int i = 0; i < ThreadCount; i++)
{
_Threads[i].Start();
}
}
private void Do(object obj)
{
while (bLoop)
for (int i = 0; i < ObjectCount; i++)
{
if (!bLoop) break;
Test oTest;
lock (_TestS.SyncRoot)
{
oTest = _TestS[i];
}
lock (oTest.SyncRoot)
{
oTest.DoSomething();
}
}
}
private void btnStop_Click(object sender, EventArgs e)
{
bLoop = false;
}
}
public class Test:IDisposable
{
public object SyncRoot = new object();
public void DoSomething()
{
System.Threading.Thread.Sleep(10);
}
public void Dispose()
{
SyncRoot = null;
}
}
Handles count will increase about the value ObjectCount has!! (here is about 1000)
If I Stop it and agin start it, handles will increase again.
I tested System.GC.Collect(); System.GC.WaitForPendingFinalizers();
here and they seem that they work!! ( so handles are decreased and again increased.)
And I found one problem or maybe a bug in .net :
when I create a thread, OS or ... creates 4 handles for that. After the thread terminates, OS or ... will not realease those handles! So there are some Handles leak when we continuing create new threads. ( Thread pool is solved the problem)
And one thing else:
lock (object) {} will not increase the handles count if there are no other competitors! ( So I think in this situation, it does not call CLREvent::CreateMonitorEvent)