C# Monitor работает вообще ?
От: Rumata_V Украина  
Дата: 12.10.06 11:45
Оценка:
Собственно долго ломал голову и так и не нашел ответа на вопрос почему...

задача простая... лог со скроллом вниз, Если количество строчек больше заданного числа, последняя строчка удаляется.

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? и в каких случаях, потому что в случае написанного в МСДН он не работает... или я не так понял?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.