Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Синхронизованное свойство, пытаюсь разобраться, появились вопросы 
:(
    Опции темы
YoungMan
Дата 15.7.2006, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.7.2006

Репутация: нет
Всего: нет



Это я уже понял.
Решая данную задачу через ReaderWriterLock класс, у сеня получилось так:
    
Код

public class MyClass
    {        
        #region Конструктор
        /// <summary>
        /// Конструктор класса
        /// </summary>
        public MyClass()
        {
            oEmpl = new Employee();
            rnd = new Random();
            rwl = new ReaderWriterLock();
        }
        #endregion

        #region Поля класса
        /// <summary>
        /// Объект класса сотрудник
        /// </summary>
        private Employee oEmpl = null;
        /// <summary>
        /// Определяет блокировку с возможностью одновременного множественного чтения и одничной записи
        /// </summary>
        public static ReaderWriterLock rwl;
        /// <summary>
        /// Реализация случайной величины
        /// </summary>
        private Random rnd;
        #endregion

        #region Открытые свойства класса
        /// <summary>
        /// "Синхронизированное"  свойство чтения(записи) информации о сотруднике
        /// </summary>
        public Employee SharedRes
        {
            get
            {
                try
                {
                    rwl.AcquireReaderLock(1000);
                    try
                    {
                        Employee tEmpl;
                        tEmpl = this.oEmpl;
                        Thread.Sleep(rnd.Next(20));
                        return tEmpl;
                    }
                    finally
                    {
                        rwl.ReleaseReaderLock();
                    }
                }
                catch(Exception)
                {
                    return null;
                }

            }
            set
            {
                try
                {
                    rwl.AcquireWriterLock(1000);
                    try
                    {
                        this.oEmpl.fname = value.fname;
                        Thread.Sleep(rnd.Next(20));
                        this.oEmpl.lname = value.lname;
                        Thread.Sleep(rnd.Next(20));
                        this.oEmpl.Age = value.Age;
                        Thread.Sleep(rnd.Next(20));
                    }
                    finally
                    {
                        rwl.ReleaseWriterLock();
                    }
                }
                catch(Exception)
                {
                }

            }
        }

        #endregion
    }

Но у меня все равно иногда проскакивает "скомканный вывод", чего быть по идее не долно.
класс вызова:
Код

    public class ThreadApp : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button btnStrStp;
        private System.Windows.Forms.ListBox listBox;

        /// <summary>
        /// Флаг запуска(остановки) приложения
        /// </summary>
        private bool bStrStp;
        /// <summary>
        /// Переменная класса чтения/записи
        /// </summary>
        private MyClass m;
        /// <summary>
        /// Количиство "писателей"
        /// </summary>
        private static int iWriter;
        /// <summary>
        /// Количиство "читателей"
        /// </summary>
        private static int iReader;
        /// <summary>
        /// Общее количетво потоков
        /// </summary>
        int iNemberOfTreads = 12;        
        /// <summary>
        /// Массив потоков
        /// </summary>
        Thread[] tPool;

        static ReaderWriterLock rwl = new ReaderWriterLock();

        private System.ComponentModel.Container components = null;

        public ThreadApp()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            CustomInitialize();
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.listBox = new System.Windows.Forms.ListBox();
            this.btnStrStp = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // listBox
            // 
            this.listBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right)));
            this.listBox.Location = new System.Drawing.Point(8, 0);
            this.listBox.Name = "listBox";
            this.listBox.Size = new System.Drawing.Size(304, 329);
            this.listBox.TabIndex = 0;
            // 
            // btnStrStp
            // 
            this.btnStrStp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.btnStrStp.Location = new System.Drawing.Point(320, 8);
            this.btnStrStp.Name = "btnStrStp";
            this.btnStrStp.Size = new System.Drawing.Size(96, 24);
            this.btnStrStp.TabIndex = 1;
            this.btnStrStp.Text = "Пуск";
            this.btnStrStp.Click += new System.EventHandler(this.btnStrStp_Click);
            // 
            // ThreadApp
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(416, 334);
            this.Controls.Add(this.btnStrStp);
            this.Controls.Add(this.listBox);
            this.Name = "ThreadApp";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// Точка входа приложения
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new ThreadApp());
        }
        
        /// <summary>
        /// Обработка событий нажатия кнопки (Запуск/Остановка приложения)
        /// </summary>
        /// <param name="sender">Ресурс события</param>
        /// <param name="e">Информация о событии</param>
        private void btnStrStp_Click(object sender, System.EventArgs e)
        {
            //Изменение значения флага запуска(остановки)
            bStrStp = !bStrStp;

            // Запуск / остановка приложения
            if (!bStrStp)
            {
                for(int i=0; i<iNemberOfTreads; i++)
                {
                    tPool[i].Join();
                }                
                btnStrStp.Text = "Пуск";
            }
            else
            {
                Start();
                btnStrStp.Text = "Остановка";
            }
            
        }

        /// <summary>
        /// Определение пользовательских переменных
        /// </summary>
        private void CustomInitialize()
        {
            bStrStp = false;
            m = new MyClass();
            iWriter = 0;
            iReader = 0;
            tPool = new Thread[iNemberOfTreads];

        }
        /// <summary>
        /// Функция запуска приложения
        /// </summary>
        private void Start()
        {
            //Формирование потоков чтения/записи
            for(int i = 0; i<iNemberOfTreads; i++)
            {
                if (i%6 == 0)
                    //поток "писатель"
                    tPool[i] = new Thread(new ThreadStart(Write));
                else
                    //поток "читатель"
                    tPool[i] = new Thread(new ThreadStart(Read));
                tPool[i].Name = new String(Convert.ToChar(i + 65), 1);
                tPool[i].Start();
                Thread.Sleep(10);
            }
        }
        /// <summary>
        /// Функция записи данных о сотруднике
        /// </summary>
        private void Write()
        {
            int iWriterIndex = ++iWriter;
            int index = 0;
            while(bStrStp)
            {
                string sFName = "Имя_" + iWriterIndex.ToString() + "_" + (++index).ToString();
                string sLName = "Фамилия_"+ iWriterIndex.ToString() + "_" + index.ToString();
                int iAge = iWriterIndex*1000 + index;
                m.SharedRes = new Employee(sFName, sLName, iAge);
                listBox.Items.Add("Writer (" + iWriterIndex + "): Выполнен " + index.ToString());
            }
        }
        /// <summary>
        /// Функция чтения данных о сотруднике
        /// </summary>
        private void Read()
        {
            int iReaderIndex = ++iReader;
            int index = 0;
            while(bStrStp)
            {
                ++index;
                try
                {
                    rwl.AcquireReaderLock(1000);
                    try
                    {
                        Employee oEmpl = m.SharedRes;
                        if (!(oEmpl == null))
                            listBox.Items.Add("Reader (" + iReaderIndex + "|" + index.ToString() + "): " + oEmpl.fname + "*" + oEmpl.lname + "*" + oEmpl.Age.ToString());
                    }
                    finally
                    {
                        rwl.ReleaseReaderLock();            
                    }    
                }
                catch(Exception)
                {
                }
            }
        }

    }

Не подскажите что я не правильно делаю? 
PM MAIL   Вверх
YoungMan
Дата 15.7.2006, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.7.2006

Репутация: нет
Всего: нет



сори, вот новый новый класс вызова:
Код

    public class ThreadApp : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button btnStrStp;
        private System.Windows.Forms.ListBox listBox;

        /// <summary>
        /// Флаг запуска(остановки) приложения
        /// </summary>
        private bool bStrStp;
        /// <summary>
        /// Переменная класса чтения/записи
        /// </summary>
        private MyClass m;
        /// <summary>
        /// Количиство "писателей"
        /// </summary>
        private static int iWriter;
        /// <summary>
        /// Количиство "читателей"
        /// </summary>
        private static int iReader;
        /// <summary>
        /// Общее количетво потоков
        /// </summary>
        int iNemberOfTreads = 12;        
        /// <summary>
        /// Массив потоков
        /// </summary>
        Thread[] tPool;

        private System.ComponentModel.Container components = null;

        public ThreadApp()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            CustomInitialize();
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.listBox = new System.Windows.Forms.ListBox();
            this.btnStrStp = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // listBox
            // 
            this.listBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right)));
            this.listBox.Location = new System.Drawing.Point(8, 0);
            this.listBox.Name = "listBox";
            this.listBox.Size = new System.Drawing.Size(304, 329);
            this.listBox.TabIndex = 0;
            // 
            // btnStrStp
            // 
            this.btnStrStp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.btnStrStp.Location = new System.Drawing.Point(320, 8);
            this.btnStrStp.Name = "btnStrStp";
            this.btnStrStp.Size = new System.Drawing.Size(96, 24);
            this.btnStrStp.TabIndex = 1;
            this.btnStrStp.Text = "Пуск";
            this.btnStrStp.Click += new System.EventHandler(this.btnStrStp_Click);
            // 
            // ThreadApp
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(416, 334);
            this.Controls.Add(this.btnStrStp);
            this.Controls.Add(this.listBox);
            this.Name = "ThreadApp";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// Точка входа приложения
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new ThreadApp());
        }
        
        /// <summary>
        /// Обработка событий нажатия кнопки (Запуск/Остановка приложения)
        /// </summary>
        /// <param name="sender">Ресурс события</param>
        /// <param name="e">Информация о событии</param>
        private void btnStrStp_Click(object sender, System.EventArgs e)
        {
            //Изменение значения флага запуска(остановки)
            bStrStp = !bStrStp;

            // Запуск / остановка приложения
            if (!bStrStp)
            {
                for(int i=0; i<iNemberOfTreads; i++)
                {
                    tPool[i].Join();
                }                
                btnStrStp.Text = "Пуск";
            }
            else
            {
                Start();
                btnStrStp.Text = "Остановка";
            }
            
        }

        /// <summary>
        /// Определение пользовательских переменных
        /// </summary>
        private void CustomInitialize()
        {
            bStrStp = false;
            m = new MyClass();
            iWriter = 0;
            iReader = 0;
            tPool = new Thread[iNemberOfTreads];

        }
        /// <summary>
        /// Функция запуска приложения
        /// </summary>
        private void Start()
        {
            //Формирование потоков чтения/записи
            for(int i = 0; i<iNemberOfTreads; i++)
            {
                if (i%6 == 0)
                    //поток "писатель"
                    tPool[i] = new Thread(new ThreadStart(Write));
                else
                    //поток "читатель"
                    tPool[i] = new Thread(new ThreadStart(Read));
                tPool[i].Name = new String(Convert.ToChar(i + 65), 1);
                tPool[i].Start();
                Thread.Sleep(10);
            }
        }
        /// <summary>
        /// Функция записи данных о сотруднике
        /// </summary>
        private void Write()
        {
            int iWriterIndex = ++iWriter;
            int index = 0;
            while(bStrStp)
            {
                string sFName = "Имя_" + iWriterIndex.ToString() + "_" + (++index).ToString();
                string sLName = "Фамилия_"+ iWriterIndex.ToString() + "_" + index.ToString();
                int iAge = iWriterIndex*1000 + index;
                m.SharedRes = new Employee(sFName, sLName, iAge);
                listBox.Items.Add("Writer (" + iWriterIndex + "): Выполнен " + index.ToString());
            }
        }
        /// <summary>
        /// Функция чтения данных о сотруднике
        /// </summary>
        private void Read()
        {
            int iReaderIndex = ++iReader;
            int index = 0;
            while(bStrStp)
            {
                ++index;
                Employee oEmpl = m.SharedRes;
                if (!(oEmpl == null))
                    listBox.Items.Add("Reader (" + iReaderIndex + "|" + index.ToString() + "): " + oEmpl.fname + "*" + oEmpl.lname + "*" + oEmpl.Age.ToString());
            }
        }

    }


Но вопрос остается "скомканности" остается  smile  
PM MAIL   Вверх
YoungMan
Дата 15.7.2006, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.7.2006

Репутация: нет
Всего: нет



 smile А в таком варианте все нормально:
Код

public class MyClass
    {        
        #region Конструктор
        /// <summary>
        /// Конструктор класса
        /// </summary>
        public MyClass()
        {
            oEmpl = new Employee();
            rnd = new Random();
            rwl = new ReaderWriterLock();
        }
        #endregion

        #region Поля класса
        /// <summary>
        /// Объект класса сотрудник
        /// </summary>
        private Employee oEmpl = null;
        /// <summary>
        /// Определяет блокировку с возможностью одновременного множественного чтения и одничной записи
        /// </summary>
        private static ReaderWriterLock rwl;
        /// <summary>
        /// Реализация случайной величины
        /// </summary>
        private Random rnd;
        #endregion

        #region Открытые свойства класса
        /// <summary>
        /// "Синхронизированное"  свойство чтения(записи) информации о сотруднике
        /// </summary>
        public Employee SharedRes
        {
            get
            {
                //чтенение данных о сотруднике
                try
                {
                    rwl.AcquireReaderLock(1000);
                    try
                    {
                        //Создание копии объета сотрудника
                        Employee tEmpl = new Employee();
                        //Чтение имени
                        tEmpl.fname = this.oEmpl.fname;
                        Thread.Sleep(rnd.Next(100));
                        //Чтение фамилии
                        tEmpl.lname = this.oEmpl.lname;
                        Thread.Sleep(rnd.Next(100));
                        //Чтение возраста
                        tEmpl.Age = this.oEmpl.Age;
                        Thread.Sleep(rnd.Next(100));
                        return tEmpl;
                    }
                    finally
                    {
                        rwl.ReleaseReaderLock();
                    }
                }
                catch(Exception)
                {
                    return null;
                }

            }
            set
            {
                //запись данных о сотруднике
                try
                {
                    rwl.AcquireWriterLock(1000);
                    try
                    {
                        //Запись имени сотрудника
                        this.oEmpl.fname = value.fname;
                        Thread.Sleep(rnd.Next(500));
                        //Запись фамилии сотрудника
                        this.oEmpl.lname = value.lname;
                        Thread.Sleep(rnd.Next(500));
                        //Запись возраста сотрудника
                        this.oEmpl.Age = value.Age;
                        Thread.Sleep(rnd.Next(500));
                    }
                    finally
                    {
                        rwl.ReleaseWriterLock();
                    }
                }
                catch(Exception)
                {
                }

            }
        }

        #endregion
    }
 
PM MAIL   Вверх
Аленка
Дата 17.7.2006, 07:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Ну ты же сам наверно все понимаешь smile  (Это я насчет скомканности)
Ты увеличил время, через которое методы обращаются к данным, поэтому, возможно, они и успевают закончить работу, не прерываясь другими методами.
 
PM   Вверх
YoungMan
Дата 17.7.2006, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.7.2006

Репутация: нет
Всего: нет



Но время на запись (в среднем) значительно больше времени чтения чтения, т.е. больше "читателей" могут влезть.

Или я не правильно понимаю?

Может подскажешь тогда smile. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0613 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.