Callbacks (part 2, at long last)
It’s been a while since I’ve blogged (hey, we’ve been busy
). I think the best place to pick up is with the long-promised second part of our article on callbacks. In the first part, I wrote about how to register .NET classes as listeners for Java events (in .NET-to-Java projects). In this post, I’ll talk about how to write Java classes that can be registered as listeners for .NET events (in Java-to-.NET projects).
Let’s start by describing the .NET event generator class:
public delegate void MyEventHandler(string message);
public class EventGenerator
{
public event MyEventHandler myEvent;
public void fireEvents(string message)
{
myEvent(message);
}
}
public void sampleEventHandler(string message)
{
Console.WriteLine(“sample event handler: message = “ + message);
}
then designate it as a delegate and add it to the event:
myEvent += new MyEventHandler(sampleEventHandler);
void Invoke(string);
Our Java callback class must implement MyEventHandler:
{
// method implementation required by MyEventHandler
public void Invoke(String message)
{
System.out.println(“callback fired: message = ” + message);
}
}
In our Java code, we instantiate EventGenerator (by instantiating its proxy), then instantiate CallbackClass and register it with myEvent. We can do this because CallbackClass implements the proxied delegate MyEventHandler.
// create the event generator
EventGenerator eg = new EventGenerator();
// register an event handler
eg.add_myEvent(new CallbackClass());
Now, when we call eg.fireEvents(), all the registered event handlers will execute, including all Invoke() methods of registered Java-side event handlers.
Note that, just like in the .NET-to-Java situation, in Java-to-.NET projects the .NET side will suspend when it calls the Java-side callback and wait until it returns, in order to preserve the expected callback semantics. As in the .NET-to-Java situation, this can sometimes lead to deadlock, particularly in cases involving multi-threaded applications and GUIs. In the previous callback post, we discussed how this problem was addressed in .NET-to-Java projects through use of the [AsyncCallback] attribute. In Java-to-.NET projects, we do something similar: Java callback classes, in addition to implementing their proxied delegate interfaces, can also implement the marker interface com.jnbridge.jnbcore.AsyncCallback, which has no methods. When the .NET side calls a Java callback object implementing AsyncCallback, it doesn’t wait for the callback method to return, but rather continues on. This means that values returned by asynchronous callbacks, and exceptions thrown by them, are ignored.



