Собственно долго ломал голову и так и не нашел ответа на вопрос почему...
задача простая... лог со скроллом вниз, Если количество строчек больше заданного числа, последняя строчка удаляется.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace test
{
public partial class Form1 : Form
{
private List<Thread> _threads;
private bool _working = true;
public Form1()
{
InitializeComponent();
_threads = new List<Thread>();
}
private void button1_Click(object sender, EventArgs e)
{
_working = true;
Thread t;
for (int i = 0; i < 2; i++)
{
t = new Thread(new ThreadStart(ExecuteThreadProc));
_threads.Add(t);
t.Start();
label1.Text = _threads.Count.ToString();
Application.DoEvents();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_working = false;
}
private void ExecuteThreadProc()
{
int count = 0;
int threadID = Thread.CurrentThread.ManagedThreadId;
string str;
StringBuilder sb = new StringBuilder();
while(_working)
{
sb.Length = 0;
str = string.Format("ThreadID = {0}, Count={1}", threadID, count++);
for (int i = 0; i < 100; i++)
sb.AppendFormat("{0} ", threadID);
_OnMessage(str, sb.ToString());
Thread.Sleep(200);
}
}
private delegate void d_OnMessage(string str, string s);
private void _OnMessage(string str, string s)
{
if (InvokeRequired)
{
try
{
Monitor.Enter(listBox1);
int id = Thread.CurrentThread.ManagedThreadId; // это просто для контроля, чтобы быть уверенным что потоки действительно разные...
BeginInvoke(new d_OnMessage(_OnMessage), new object[] { str, s });
}
finally
{
Monitor.Exit(listBox1);
}
}
else
{
listBox1.BeginUpdate();
listBox1.Items.Insert(0, listBox1.Items.Count.ToString("D3") + " " + str + " --> " + s);
label1.Text = listBox1.Items.Count.ToString();
while (listBox1.Items.Count >= 10)
listBox1.Items.Remove(listBox1.Items.Count - 1); //!!! вот тут приложение ложится насмерть...
listBox1.EndUpdate();
}
}
private void button2_Click(object sender, EventArgs e)
{
_working = false;
_threads.Clear();
label1.Text = _threads.Count.ToString();
}
}
}
если я правильно понял... что Monitor.Enter Acquires an exclusive lock on the specified object. из МСДН.
значит код не должен одновременно выполняться одновременно... если убрать удаление, то работает
как только выполняется listBox1.Items.Remove(listBox1.Items.Count — 1); приложение ложится....
так работает ли Monitor? и в каких случаях, потому что в случае написанного в МСДН он не работает... или я не так понял?