два потока..уведомить один о событии в другом. куда копать?
От: salvequick  
Дата: 22.09.06 12:30
Оценка:
два потока..уведомить один о событии в другом. куда копать?

в первом потоке слушается сокет ....
а во втором кторый владеет формой они (данные из него) отображаются на форме ....

как сообщить во второй что данные есть и можно начинать работу?
куда копать ?
посмотреть на event или на в какую сторону?

ничег не понимаю потому как на .Net ничего не делал ... первая прога
после unix тяжеловато честно говоря...
подскажите пожалуйста!!!
Re: два потока..уведомить один о событии в другом. куда копа
От: Аноним  
Дата: 22.09.06 12:37
Оценка:
AutoResetEvent, ManualResetEvent, Mutex ... Threading namespace
Re: два потока..уведомить один о событии в другом. куда копа
От: _FRED_ Черногория
Дата: 22.09.06 12:38
Оценка:
Здравствуйте, salvequick, Вы писали:

S>два потока..уведомить один о событии в другом. куда копать?


Простая и безопасная реализация многопоточности в Windows Forms.
Автор(ы): Крис Селлз (Chris Sells)
Дата: 05.06.2003
В статье рассматривается использование многопоточности в приложениях Windows Forms на примере отображения хода длительной операции с использованием асинхронного делегата для запуска рабочего потока и метода Invoke для главной формы.
... << RSDN@Home 1.2.0 alpha rev. 652>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Re: два потока..уведомить один о событии в другом. куда копа
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 22.09.06 12:38
Оценка:
Здравствуйте, salvequick, Вы писали:

S>два потока..уведомить один о событии в другом. куда копать?


S>в первом потоке слушается сокет ....

S>а во втором кторый владеет формой они (данные из него) отображаются на форме ....

S>как сообщить во второй что данные есть и можно начинать работу?

S>куда копать ?
S>посмотреть на event или на в какую сторону?

S>ничег не понимаю потому как на .Net ничего не делал ... первая прога

S>после unix тяжеловато честно говоря...
S>подскажите пожалуйста!!!

Смотрите в сторону наследников Waithandle, в частности ManulaResetEvent и AutoResetEvent.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: два потока..уведомить один о событии в другом. куда копа
От: Pavel M. Россия  
Дата: 22.09.06 12:39
Оценка:
Здравствуйте, salvequick, Вы писали:

S>два потока..уведомить один о событии в другом. куда копать?


S>в первом потоке слушается сокет ....

S>а во втором кторый владеет формой они (данные из него) отображаются на форме ....

S>как сообщить во второй что данные есть и можно начинать работу?

S>куда копать ?
S>посмотреть на event или на в какую сторону?

S>ничег не понимаю потому как на .Net ничего не делал ... первая прога

S>после unix тяжеловато честно говоря...
S>подскажите пожалуйста!!!

в .НЕТ подобные вещи делаются на делегатах (delegate) и событиях (event). посмотреть пример в MSDN обязательно и полезно для начала =)
--------------------------
less think — do more
Re: два потока..уведомить один о событии в другом. куда копа
От: Vie dodger  
Дата: 22.09.06 12:42
Оценка:
System.Threading.Mutex
System.Threading.ManualResetEvent
System.Threading.Semaphore


Идея такая, первый просто сигнализирует второму, что данные готовы для считывания,тогда второй производит считываение и скидывает после этого флаг.
Re: два потока..уведомить один о событии в другом. куда копа
От: Аноним  
Дата: 22.09.06 12:46
Оценка:
Здравствуйте, salvequick, Вы писали:

S>два потока..уведомить один о событии в другом. куда копать?


S>в первом потоке слушается сокет ....

S>а во втором кторый владеет формой они (данные из него) отображаются на форме ....

S>как сообщить во второй что данные есть и можно начинать работу?

S>куда копать ?
S>посмотреть на event или на в какую сторону?

S>ничег не понимаю потому как на .Net ничего не делал ... первая прога

S>после unix тяжеловато честно говоря...
S>подскажите пожалуйста!!!


Один из вариантов — сделать обработчик события следующим образом

void example_DataHasCome(object sender, EventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new EventHandler(example_DataHasCome), new object[] { sender, e });
return;
}
ProcessYourData();
}

Здесь this это форма, которая будет отображать данные.

Первый раз обработчик дернется из фонового потока получения данных, InvokeRequired будет true,
так как форма выполняется в другом потоке. BeginInvoke форсирует выполнения делегата обработчика в потоке,
в котором выполняется форма. Таким образом, при вызове этого метода из нити формы, InvokeRequired == false,
данные обработаются методом ProcessYourData().
Re: два потока..уведомить один о событии в другом. куда копа
От: salvequick  
Дата: 22.09.06 12:59
Оценка:
Здравствуйте!

спасибо за советы!!
попробую копнуть
Re[2]: два потока..уведомить один о событии в другом. куда к
От: salvequick  
Дата: 22.09.06 13:03
Оценка:
Здравствуйте, Vie dodger, Вы писали:


VD>
VD>System.Threading.Mutex
VD>System.Threading.ManualResetEvent
VD>System.Threading.Semaphore
VD>


VD>Идея такая, первый просто сигнализирует второму, что данные готовы для считывания,тогда второй производит считываение и скидывает после этого флаг.



ну вот я что то типа того пытался на мутексах сделать....
че то не получилось...
тут ведь если какой либо из методов формы зависает в

while(... )
{

нечто.... 

}


т.е одна из функий основного потока?
то форма не будет отрисовываться я прав??
и вообще вся обработка сообщений зависнет?
Re[2]: два потока..уведомить один о событии в другом. куда к
От: stump http://stump-workshop.blogspot.com/
Дата: 22.09.06 14:02
Оценка:
Здравствуйте, salvequick, Вы писали:

S>Здравствуйте!


S>спасибо за советы!!

S>попробую копнуть

Ну тебе тут и насоветовали
Смотри. Есть форма. В дизайнере вытаскиваешь на нее таймер, и в форме пишешь обработчик события таймера.
Так у тебя тоже самое, только вместо таймера твой код в потоке. Обяъви событие, а в форме сделай обработчика.
Понедельник начинается в субботу
Re[3]: два потока..уведомить один о событии в другом. куда к
От: salvequick  
Дата: 22.09.06 17:21
Оценка:
Здравствуйте, stump, Вы писали:



S>Ну тебе тут и насоветовали

S>Смотри. Есть форма. В дизайнере вытаскиваешь на нее таймер, и в форме пишешь обработчик события таймера.
S>Так у тебя тоже самое, только вместо таймера твой код в потоке. Обяъви событие, а в форме сделай обработчика.

вообщем это наиболее понятно мне пока из всего....
т.е в теории мне теперь все ясно
к потоку можно прикрутить свое событие?
и просто как tick по агалогии его ообработать


а как его вызвать? и как объявить его вот чего не могу понять....
у меня есть функция потока которая является членом класса формы ...
и я даже не представляю как добавить событие к ней и обратотчик в основной поток

примечик бы... их вроде и полно и статьи там всякие ... но у меня все равно все немного по другому
Re[4]: два потока..уведомить один о событии в другом. куда к
От: stump http://stump-workshop.blogspot.com/
Дата: 23.09.06 07:48
Оценка:
Здравствуйте, salvequick, Вы писали:

S>а как его вызвать? и как объявить его вот чего не могу понять....

S>у меня есть функция потока которая является членом класса формы ...
S>и я даже не представляю как добавить событие к ней и обратотчик в основной поток

S>примечик бы... их вроде и полно и статьи там всякие ... но у меня все равно все немного по другому


Ну вот здесь
Автор: stump
Дата: 29.08.06
примерчик кода есть для такого случая.
Понедельник начинается в субботу
два потока..уведомить один о событии в другом. куда копать?
От: Аноним  
Дата: 23.09.06 08:18
Оценка:
2salvequick:
если .NET 2.0 то можешь посмотреть в сторону
http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

вот примерчик (не мой):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Data.SqlClient;
using System.Configuration;

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

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
        private BackgroundWorker worker = null;
        const int interval = 5000;
        private void Form1_Load(object sender, EventArgs e)
        {           
            worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerAsync(interval);
        }

        private void customersBindingSource_CurrentChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            refreshData();
        }
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                if (!worker.IsBusy)
                    worker.RunWorkerAsync(interval);
            }
            else {
                if (worker.IsBusy)
                    worker.CancelAsync();
            }
        }
        private void refreshData()
        {
            string strL = this.label1.Text;
            this.label1.Text = "retrieving data...";
            Application.DoEvents();
            this.customersTableAdapter.Fill(this.northwindDataSet.Customers);
            this.label1.Text = strL;
        }

        static int Counter = 0;
        SqlConnection connection = null;
        SqlCommand command = null;
        string key = "customers";
        int changeID = -1;

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            connection = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["SQLForms.Properties.Settings.NorthwindConnectionString"]);
            command = new SqlCommand("getChangeNotifications", connection);
            command.CommandType = CommandType.StoredProcedure;

            connection.Open();
            while (true)
            {
                if (InvokeRequired)
                {
                    // Deal with possible cancellation
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        break;
                    }
                    // bool dirty = (Counter % 5 == 0);
                    bool dirty = worker_Poll();
                    Invoke(new Change(OnChange), dirty);
                    System.Threading.Thread.Sleep((int)e.Argument);
                }
            }
            connection.Close();
        }
        private void OnChange(bool dirty)
        {
            this.label2.Text = (++Counter).ToString();
            if (dirty)
            {
                this.refreshData();
            }
            else
                Application.DoEvents();
        }

        private delegate void Change(bool dirty);

        #region DB Poll
        bool worker_Poll()
        {
            bool dirty = false;
            SqlDataReader reader;
            reader = command.ExecuteReader();
            while (reader.Read())
            {
                if (key == reader["Table"].ToString())
                {
                    int cid = (int)reader["ChangeID"];
                    if (changeID != cid)
                    {
                        changeID = cid;
                        dirty = true;
                    }
                    break;
                }
            }
            reader.Dispose();
            reader.Close();
            return dirty;
        }
        #endregion

        private void button2_Click(object sender, EventArgs e)
        {
            ColorDialog dlg = new ColorDialog();
            dlg.ShowDialog();
            dlg.Dispose();
        }

    }
}
-- Если тебе помогли, незабудь сказать спасибо --
-- Это всё мое личное мнение которое может не совпадать с Вашим или может быть ошибочным --

.NetCoder


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: два потока..уведомить один о событии в другом. куда копа
От: salvequick  
Дата: 25.09.06 06:13
Оценка:
Спасибо большое всем за советы !!!!!
Re: Все равно что то не пойму....
От: salvequick  
Дата: 26.09.06 06:13
Оценка:
все равно не понятно

дело в том что главнй поток не должен блокироваться...
иначе win сообщения не будут приниматься и форма как бы подвиснет...
поэтому блокировка на mutex или ManualResetEvent не подходит...

а создание делегата в котором идет вывод на экран и вызов его из потока приводит к тому что код по изменению данных
все ранво выполняется из потока а этого делать нельзя....

так что же остается то?
Re[2]: Все равно что то не пойму....
От: stump http://stump-workshop.blogspot.com/
Дата: 26.09.06 06:37
Оценка:
Здравствуйте, salvequick, Вы писали:

S>все равно не понятно


S>дело в том что главнй поток не должен блокироваться...

S>иначе win сообщения не будут приниматься и форма как бы подвиснет...
S>поэтому блокировка на mutex или ManualResetEvent не подходит...

S>а создание делегата в котором идет вывод на экран и вызов его из потока приводит к тому что код по изменению данных

S>все ранво выполняется из потока а этого делать нельзя....

S>так что же остается то?

Остается Invoke()
Допустим сейчас у тебя так:
public void OnSocketDataReceived(object socketData)
{
  // отображение полученных данных в форме
}



делаем так
public void OnSocketDataReceived(object socketData)
{
  Invoke(new VisualUpdate(OnVisualUpdate), new object[]{socketData});
}

public delegate void VisualUpdate(object data);

public void OnVisualUpdate(object data)
{
  // отображение полученных данных в форме
}
Понедельник начинается в субботу
Re[2]: Все равно что то не пойму....
От: Аноним  
Дата: 26.09.06 06:40
Оценка:
Здравствуйте, salvequick, Вы писали:

S>все равно не понятно


Самый дельный совет был (приведенный код долже выполняться в работающем с сокетом потоке):
===============
Один из вариантов — сделать обработчик события следующим образом

void example_DataHasCome(object sender, EventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new EventHandler(example_DataHasCome), new object[] { sender, e });
return;
}
ProcessYourData();
}

Здесь this это форма, которая будет отображать данные.

Первый раз обработчик дернется из фонового потока получения данных, InvokeRequired будет true,
так как форма выполняется в другом потоке. BeginInvoke форсирует выполнения делегата обработчика в потоке,
в котором выполняется форма. Таким образом, при вызове этого метода из нити формы, InvokeRequired == false,
данные обработаются методом ProcessYourData().
Re[2]: Спасибо !! вроде работает...
От: salvequick  
Дата: 26.09.06 11:51
Оценка:
Спасибо !! вроде работает...

invoke меня спас!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.