Question

We are working on integrating two different applications that run simultaneously and share data. One application provides the data, the other one computes some values based off external systems and the data and has to provide it back to the first application.

We are using this library to share the data between the applications: http://grouplab.cpsc.ucalgary.ca/cookbook/index.php/Toolkits/Networking

The library basically allows to create a shared dictionary which can be queried by any application (as long as it knows the location of the shared dictionary).

So, what should happen is program A has to provide some data to program B and program B uses this data and returns some other data back to program A.

My problem is how do I make the program A wait for the response from B. In more concrete terms, I can put an object in the shared dictionary, the other program gets notified of a change in the dictionary, it can compute some attribtues and update the object in the dictionary. Program A can get notified, but I want program A to wait till it gets back this response - program A's action should be based on the returned value.

A very ugly way I see this can be done is have an infinite loop inside the function, that keeps querying the dictionary to see if the object has been udpated - if it has break out of the loop and use the object and its computed attributes. Does anyone know of a nicer solution?

Was it helpful?

Solution

Using their subscription model, you are able to avoid all infinite-looping. Why would you need to loop when the only times you need to check is when something is actually updated? Since you subscribe to key patterns in the dictionary and your connection will be notified when a key fitting that pattern is updated/added, you only need to check on that.

So basically, you can use a ManualResetEvent to wait for synchronization within your own system. Here is an example of usage of 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);
    }
}

To translate to your framework, you might have the subscription handler check what was updated, find that wait handle and signal it, thus advancing the proper waiting threads.

OTHER TIPS

use a ManualResetEvent.

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

Without using other methods of IPC (since you've seemed to settle on this particular library) it would seem to me that continuous polling is about the only way. If you are willing (and able) to implement other IPC methods then you should discontinue use of the current library and just pass the data between the programs yourself.

If I understand correctly, Program A mustn't execute any additional logic until Program B has updated the value, and Program A can get a notification of said update from that system out of UCalgary.

Based on those assumptions, I'd suggest that after sending data to the shared dictionary, you start a timer whose Tick event is handled by a method that will either (a) check the dictionary for updates, or (b) check a variable that gets set by the notification that comes in from the shared dictionary library.

Once the update has been found, stop the timer, and execute the method that will pick up processing the newly updated value.

The timer is not unlike the "infinite loop" you suggested, but it has virtually no processing overhead, can be set to check at a realistic interval (be that 1 second, 1 minute, 24 hours), and can be set up to time out if things don't go as planned with Program B or the dictionary.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top