Функция ожидает ответа от другого приложения


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

Мы используем эту библиотеку для обмена данными между приложениями: http://grouplab.cpsc.ucalgary.ca/cookbook/index.php/Toolkits/Networking

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

Итак, программа A должна предоставить некоторые данные программе B, и программа B использует эти данные и возвращает некоторые другие данные обратно в программу A.

Моя проблема заключается в том, как заставить программу A ждать ответа от B. Более конкретно, я могу поместить объект в общий словарь, другая программа получает уведомление об изменении в словаре, она может вычислите некоторые атрибуты и обновите объект в словаре. Программа а может получить уведомление, но я хочу, чтобы программа а подождала, пока она не получит обратно этот ответ - действие программы а должно основываться на возвращенном значении.

Очень уродливый способ, который я вижу, это сделать, это иметь бесконечный цикл внутри функции, которая продолжает запрашивать словарь, чтобы увидеть, был ли объект UDP-если он вырвался из цикла и использует объект и его вычисляемые атрибуты. Кто-нибудь знает о более приятном решение?

4 2

4 ответа:

Используя их модель подписки, Вы можете избежать всех бесконечных циклов. зачем вам понадобился цикл, когда единственный раз, когда вам нужно проверить, это когда что-то действительно обновляется? поскольку вы подписываетесь на ключевые шаблоны в словаре, и ваше соединение будет уведомлено, когда ключ, соответствующий этому шаблону, будет обновлен / добавлен, вам нужно только проверить это.

Таким образом, вы можете использовать ManualResetEvent для ожидания синхронизации в вашей собственной системе. Вот пример использования ManualResetEvent:
using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        //    create the reset event -- initially unsignalled
        var resetEvent = new ManualResetEvent(false);
        //    information will be filled by another thread
        string information = null;

        //    the other thread to run
        Action infoGet = delegate
        {
            //    get the information
            information = Console.ReadLine();
            //    signal the event because we're done
            resetEvent.Set();
        };

        //    call the action in a seperate thread
        infoGet.BeginInvoke(null, null);
        //    wait for completion
        resetEvent.WaitOne();
        //    write out the information
        Console.WriteLine(information);
    }
}

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

Используйте ManualResetEvent.

 // machine A
 var event = new ManualResetEvent(false);
 B_Listener.OnChanged += delegate { event.Set(); }
 myDictionary.UpdateValue();
 event.WaitOne();

Без использования других методов IPC (поскольку вы, кажется, остановились на этой конкретной библиотеке) мне кажется, что непрерывный опрос-это единственный способ. Если вы хотите (и можете) реализовать другие методы IPC, то вам следует прекратить использование текущей библиотеки и просто передать данные между программами самостоятельно.

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

Исходя из этих предположений, я бы предложил, чтобы после отправки данных в общий словарь вы запустили таймер, событие Tick которого обрабатывается методом, который либо (а) проверяет словарь на наличие обновлений, либо (б) проверяет переменную, которая устанавливается уведомлением, поступающим от пользователя. общая библиотека словарей.

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

Таймер не отличается от предложенного вами "бесконечного цикла", но он практически не требует затрат на обработку, может быть настроен на проверку с реалистичным интервалом (будь то 1 секунда, 1 минута, 24 часа) и может быть настроен на тайм-аут, если все идет не так, как планировалось с программой B или словарем.