Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Аналог очереди сообщений в потоке

4.3K
09 января 2007 года
VasAlVit
33 / / 03.09.2004
Может вопрос гупый, но всё же.

В C++ я создаю поток. в этом потоке - очередь сообщений. При необходимости что-нибудь сделать, в эту очередь помещается сообщение. Сообщения выполняются ПОСЛЕДОВАТЕЛЬНО, причём вызывающие потоки не останавливаются. Все счастливы, все довольны :)

Как реализовать подобное на C#? Т.е. есть ли возможность посылать сообщения в поток?

И ещё вопрос. Если два метода одного объекта вызываются через BeginInvoke, то гарантируется ли то, что они выполнятся ПОСЛЕДОВАТЕЛЬНО?

ps. У меня проблемы с синхронизацией :( Система сама создаёт поток для формы и поток для COM-порта. Получается что связывающий объект (который обрабатывает данные от формы и от порта) работает в двух потоках одновременно :(. Отсюда и проблемы.
273
09 января 2007 года
3A3-968M
1.2K / / 22.12.2005
Два метода, вызванные асинхронно пр помощи BeginInvoke завершаться по разному вне зависимости от того, кто первый был запущен. Для того, чтобы доджаться завершения метода, вызовите EndInvoke, что вызовет синхронизацию. И объекты UI и объект SerialPort выполняются в одном потоке. Просто события, возникающие в интерфейсе и COM-порте асинхронны. Потоки умеют общаться через методы Thread.Pulse и Thread.PulseAll. Есть конечно структура System.Windows.Forms.Message, которая предоставляет функционал Windows-сообщения.
4.3K
09 января 2007 года
VasAlVit
33 / / 03.09.2004
Нет. События формы и события SerialPort'а выполняются в разных потоках, т.к. при попытке в событии SerialPort что-нибудь сделать с формой (или её контролами), вываливается исключение. А если использовать Invoke/BeginInvoke, тогда всё нормально.

По поводу BeginInvoke. Просто есть много методов. Они никак не взаимосвязаны, но вызываются из разных потоков. Нужно, чтобы все они выполнялись в одном потоке.

Т.е. грубо говоря. Пусть два потока хотят одновременно записать данные в порт. Последовательность этих действий не важна. Важно только, чтобы пока идёт запись данных первого потока, данные второго потока ожидали "своей очереди".
Пример не очень удачный. На самом деле всё намного сложнее. Но надеюсь, что это пример передал суть вопроса:)
303
10 января 2007 года
makbeth
1.0K / / 25.11.2004
Вот вариант с очередью сообщений в потоке:
Код:
class COMPortThread
{
    // Очередь с данными для COM порта
    // COMData - класс, хранящий данные для передачи в COM порт
    // (по сути - сообщение COM порту)
    private Queue<COMData> dataQueue;
    // Событие, сигнализирующее о доступности данных в очереди
    private ManualResetEvent dataAvailable;

    //...

    // Этот метод является основным методом потока
    private void ThreadProc()
    {
         // Цикл посылки данных
         // (на самом деле он, естественно, должен быть не бесконечным)
         while(true)
         {
             // Ожидаем поступления данных в очередь
             dataAvailable.WaitOne();
             // Получаем очередные данные
             COMData data = GetData();
             // Здесь посылаем данные в COM порт
             // и выполняем другие необходимые действия
             // ...
         }    
    }
   
    private COMData GetData()
    {
        COMData result;
        lock(dataQueue)
        {
             //  Получаем очередные данные
             result = dataQueue.Dequeue();
             // Если очередь пуста - сбрасываем событие доступности данных
             if(dataQueue.Count == 0) dataAvailable.Reset();
        }
        return result;
    }
   
    // Метод посылки данных из других потоков
    public void Send(COMData data)
    {
        lock(dataQueue)
        {
            // Помещаем данные в очередь
            dataQueue.Enqueue(data);
            // Устанавливаем событие доступности данных
            dataAvailable.Set();
        }
    }
}

Чтобы послать данные из другого потока просто вызывается метод Send. Если данных нет, то поток простаивает в ожидании установки события dataAvailable. В коде опущено создание и завершение потока, но думаю, это не представляет сложности.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог