Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Помогите с событиями в C#


Автор: radiks 4.4.2008, 15:03
Приведите, пожалуйста, простой пример работы с событиями.
Например, как в реальном времени в textbox'е отобразить изменение в цикле переменной

Автор: _hunter 4.4.2008, 15:32
А ты книгу какую-нить читать не пробовал?..
+ не понятно зачем в описанной задаче события -- оно и без них прекрасно делается...
++ ты не поверишь, но в MSDN'е этих примеров -- хоть засыпся:
http://msdn2.microsoft.com/en-us/library/aa645739(VS.71).aspx

Автор: radiks 4.4.2008, 16:20
спасибо за ответ.
Читать-то я читал, да только о делегатах и событиях там в консоли примеры...
Вообще-то я начинающий в C# так, что не взыщите  smile 

Автор: source777 4.4.2008, 23:40
Цитата(_hunter @  4.4.2008,  15:32 Найти цитируемый пост)
+ не понятно зачем в описанной задаче события -- оно и без них прекрасно делается...
Насколько я понял, у radiks чисто теоретический учебный вопрос...

2radiks Вот тебе пример работы с событиями без консоли, хотя в следующий раз тебе следует более подробно объяснять чего ты в итоге хотел бы увидеть, а не играть с нами в "Битву экстрасенсов":
Код

using System;
using System.Windows.Forms;

namespace TestEvent
{
    public sealed class IterateEventArgs: EventArgs
    {
        private static int curr_value=0;
        public IterateEventArgs()
        {
            curr_value++;
        }
        public int CurrValue { get { return curr_value; } }
    }
    public sealed class IterateIt
    {
        public event EventHandler<IterateEventArgs> IterateEvent;
        private void OnIterate()
        {
            EventHandler<IterateEventArgs> handler = IterateEvent;
            if (handler != null)
            {
                handler(this, new IterateEventArgs());
            }
        }
        public void IncValue()
        {
            OnIterate();
        }

    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void OnIter(object sender, IterateEventArgs e)
        {
            textBox1.Text = e.CurrValue.ToString();
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            IterateIt iter = new IterateIt();
            iter.IterateEvent += this.OnIter;
            iter.IncValue();
        }
    }
}




Автор: radiks 7.4.2008, 08:44
 Вообще-то задача такая: прочитать текст из файла и в реальном режиме отображать каждую строку на форме (именно построчно, а не весь текст сразу). Я так понимаю без делегатов и событий тут не обойтись.
Вроде все сделал работает, но в контроле отображается только одна строка. Срабатывает только тогда, когда я это событие отрабатываю через таймер...

Спасибо за пример. Буду разбираться

Автор: source777 7.4.2008, 21:41
Цитата(radiks @  7.4.2008,  08:44 Найти цитируемый пост)
 Вообще-то задача такая: прочитать текст из файла и в реальном режиме отображать каждую строку на форме (именно построчно, а не весь текст сразу). Я так понимаю без делегатов и событий тут не обойтись.
Да что ты, тут всё гораздо проще:
Код

    public partial class Form1 : Form
    {
        private StreamReader sr;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sr = new StreamReader(@"C:\test.txt");
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!sr.EndOfStream) textBox1.Text = sr.ReadLine();
        }
    }



Автор: radiks 8.4.2008, 10:04
А без таймера это можно реализовать?!
Через события. При чтении новой строки вызвать событие, и через делегат  отобразить строку. Или я чего-то не понимаю?

Автор: tol05 8.4.2008, 10:44
можно. И это будет самым правильным (ИМХО) способом.


Автор: ivashkanet 8.4.2008, 11:00
Не понимаю зачем нужны здесь события  smile 

События нужны только в том случае когда объект выбрасывающий событие !ничего! не знает про тех кто его будут обрабатывать.

Тут же все друг друга знают и все друг друга видят. Зачем здесь событие?

Цитата(radiks @  7.4.2008,  08:44 Найти цитируемый пост)
прочитать текст из файла и в реальном режиме отображать каждую строку на форме (именно построчно, а не весь текст сразу)

Налицо две операции: одна читает данные с файла, другая  обновляет форму.
И проблема заключается в том, что GUI (форма) просто не отрисовывается пока весь файл не прочтется, так как операции идут одна за другой, а не параллельно.

Как добиться параллельного использования:
1) Либо использовать http://rsdn.ru/article/dotnet/WinForms20.xml#E3ZAG (именно он наиболее приспособлен для реализации многопоточности в GUI)
2) Либо использовать псевдомногопоточность реализуемую Application.DoEvents()
3) System.Threading.Thread даже не стоит и рассматривать. Не нужно решать высокоуровневые (GUI)  вопросы низкоуровнемыми инструментами.

Второй наиболее быстрый по скорости реализации, первый все же общепринятый подход.

Код для второго случая:
Код

        private void button1_Click(object sender, EventArgs e)
        {
            sr = new StreamReader(@"C:\test.txt");

            if (!sr.EndOfStream) 
            {
                textBox1.Text = sr.ReadLine();

                Application.DoEvents(); // Только эта строчка добавляется
            }
        }


Добавлено через 1 минуту и 36 секунд
Цитата(ivashkanet @  8.4.2008,  11:00 Найти цитируемый пост)
                textBox1.Text = sr.ReadLine();

Скопировал бездумно код. ИМХО, нужно не заменять текст, а накапливать его в текстбоксе:
Код

                textBox1.Text += sr.ReadLine(); // += вместо =

Автор: tol05 8.4.2008, 11:10
ммм. не вчитался в тему... Согласен. 

Цитата(ivashkanet @  8.4.2008,  10:00 Найти цитируемый пост)
2) Либо использовать псевдомногопоточность реализуемую Application.DoEvents()

будет "грузить" форму


Цитата(ivashkanet @  8.4.2008,  10:00 Найти цитируемый пост)
3) System.Threading.Thread даже не стоит и рассматривать. Не нужно решать высокоуровневые (GUI)  вопросы низкоуровнемыми инструментами.

не такой уж Thread и низкоуровневый smile А BackgroundWorker отличается тем, что берет тот же Thread из пула (через BeginInvoke метода при асинхронном старте worker-а),.. но поток все-таки нужен в любом случае, согласен.

Автор: ivashkanet 8.4.2008, 11:31
Цитата(tol05 @  8.4.2008,  11:10 Найти цитируемый пост)
ммм. не вчитался в тему...

Я ее тоже не сразу понял smile Где-то с третьего прочтения.
Цитата(tol05 @  8.4.2008,  11:10 Найти цитируемый пост)
будет "грузить" форму

Не согласен. DoEvents() это всего лишь передача процессорного времени оброботчику сообщений приложения.
И если делать это почаще (а ReadLine и сеттер Text работают очень быстро), то никто ничего не заметит.
Но еще раз говорю: DoEvents() -- корявка, которая решает только небольшой круг задач многопоточночти для форм, но зато их решает просто замечательно (как с точки зрения скорости получения результата, так и с точки зрения понятности).

И для этой задачи он идеален. Но повторю: только для этой (выполнить асинхронно !маленький! кусок функциональности).
Цитата(tol05 @  8.4.2008,  11:10 Найти цитируемый пост)
не такой уж Thread и низкоуровневый

Ну да, есть еще ниже его. 
Но все же для GUI специально сделали Воркер (о котором у меня самые положительные впечатления).
Не нжуно заморачивать на делегатах, инвоках, синхронизации и тыды...

Автор: radiks 8.4.2008, 11:33
Спасибо за разьяснения. А можно все-таки примерчик с делегатами.  smile 

Автор: ivashkanet 8.4.2008, 11:37
radiks, они не смогут решить проблему. Они не дают ассинхронности. Они только добавляют возможность абстрагироваться от тех кто будет обрабатывать твое сообщение.

Автор: radiks 8.4.2008, 12:01
Добавил Application.DoEvents()... и ничего не изменилось

Автор: ivashkanet 8.4.2008, 13:52
Смутил код:
Цитата(source777 @  7.4.2008,  21:41 Найти цитируемый пост)
if (!sr.EndOfStream) textBox1.Text = sr.ReadLine();

А почему if, а почему =?
Цитата(radiks @  7.4.2008,  08:44 Найти цитируемый пост)
 Вообще-то задача такая: прочитать текст из файла и в реальном режиме отображать каждую строку на форме (именно построчно, а не весь текст сразу)

Может я не понял задачу?
Тебе что нужно?
1) Добавлять каждую новую строку к уже прочитанному тексту?  //тогда просто замени if на while
2) Показывать только последнюю прочитанную строку (именно поэтому if и =)? // тогда зачем тебе это? ты все равно ничего не успеешь прочитать не замедляя процесс, а в этом случае без таймера не обойтись.


P.S. Если все же вариант 2: source777, где ты учился на телепата?

Автор: mr.DUDA 11.4.2008, 10:04

M
mr.DUDA
Дальнейшее обсуждение производительности ReadLine и т.п. тут.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)