Функция ожидает ответа от другого приложения - PullRequest
2 голосов
/ 21 января 2010

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

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

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 21 января 2010

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

Таким образом, вы можете использовать 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);
    }
}

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

1 голос
/ 21 января 2010

использовать ManualResetEvent.

 // machine A
 var event = new ManualResetEvent(false);
 B_Listener.OnChanged += delegate { event.Set(); }
 myDictionary.UpdateValue();
 event.WaitOne();
0 голосов
/ 21 января 2010

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

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

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

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

0 голосов
/ 21 января 2010

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

...