В.NET, в чем будет обработан поток События?

Я попытался реализовать шаблон производителя/потребителя в c#. Я сделал, чтобы потребитель распараллелил, который контролирует общую очередь и поток производителя, который помещает объекты на общую очередь. Поток производителя подписан для получения данных... то есть, это имеет обработчик событий, и просто сидит без дела и ожидает события OnData для увольнения (данные отправляются от стороннего API). Когда это получает данные, это прикрепляет его на очередь, таким образом, потребитель может обработать его.

Когда событие OnData действительно стреляет в производителя, я ожидал, что это будет обработано моим потоком производителя. Но это, кажется, не то, что происходит. Событие OnData кажется, как будто оно обрабатывается на новом потоке вместо этого! Это то, как .NET всегда работает..., события обрабатываются на их собственном потоке? Я могу управлять тем, какой поток обработает события, когда они будут повышены? Что, если бы сотни событий генерируются почти одновременно..., у каждого был бы его собственный поток?

50
задан John Saunders 16 March 2010 в 18:07
поделиться

4 ответа

Перечитав вопрос, я думаю, что теперь понимаю проблему. По сути, у вас есть что-то вроде этого:

class Producer
{
    public Producer(ExternalSource src)
    {
        src.OnData += externalSource_OnData;
    }

    private void externalSource_OnData(object sender, ExternalSourceDataEventArgs e)
    {
        // put e.Data onto the queue
    }
}

И затем у вас есть поток потребителя, который извлекает данные из этой очереди. Проблема в том, что событие OnData запускается вашим объектом ExternalSource - в любом потоке, в котором оно выполняется.

События C # в основном представляют собой простой в использовании набор делегатов, и «запуск» события просто заставляет среду выполнения перебирать всех делегатов и запускать их по одному.

Итак, ваш обработчик событий OnData вызывается в любом потоке, в котором работает ExternalSource .

87
ответ дан 7 November 2019 в 10:42
поделиться

Если вы сами не сделаете маршалинг, событие будет выполняться в любом потоке, который его вызывает; нет ничего особенного в том, как вызываются события, и ваш поток производителя не имеет обработчика событий, ваш поток производителя просто сказал: "Эй, когда вы вызываете это событие, вызовите эту функцию". Там нет ничего, что заставило бы выполнение события происходить в прикрепляющем потоке или в собственном потоке (если только вы не используете BeginInvoke вместо обычного вызова делегата события, но это просто выполнит его в ThreadPool).

23
ответ дан 7 November 2019 в 10:42
поделиться

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

AutoResetEvent pro = new AutoResetEvent(false);
AutoResetEvent con = new AutoResetEvent(true);

public void produser()
{

    while(true)
    {
        con.WaitOne();

        pro.Set();
    }
}

public void consumer()
{
    while (true)
    {
    pro.WaitOne();
       .................****

    con.Set();
    }
}

private void button1_Click(object sender, EventArgs e)
{
    Thread th1 = new Thread(produser);
    th1.Start();
    Thread th2 = new Thread(consumer);
    th2.Start();
}
-4
ответ дан 7 November 2019 в 10:42
поделиться

Создание события с помощью Invoke аналогично вызову метода - оно выполняется в том же потоке, в котором вы его создали.

Вызов события с помощью BeginInvoke использует ThreadPool . Вот некоторые второстепенные подробности

10
ответ дан 7 November 2019 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: