Programming Gtk# Interfaces using C# language on Af-Arch

Introduction

This document will explain you how to using Af-Arch# services to program Gtk# (http://gtk-sharp.sf.net) client interfaces using .NET C# language.

Making request using AfArch#

There are two methods to invoke services inside the Af-Arch framework using .NET C# binding provided by Af-Arch# package.

Assuming you already have generated C# bindings for your component you are trying to connect to (using af-gen), this two methods are:

  1. Using the API directly (Synchronous way):
         // launch my request
         NulData response = car.Remove ();
     
         // process request response
         if (response.State != State.Ok) 
         {
            System.Console ("Unable to remove my car: " + car.Id);
            return;
         }
    
  2. Using the Asynchronous .NET interface:
        // launch async request 
        void RemoveMyCar () 
        {
     
           // create the delegate
           Remove dlgt = new Remove (Cars.Remove);
     
           // invoke the delegate so the .NET VM creates a new
           // thread which actually runs my request
           dlgt.BeginInvoke (new AsyncCallback (RemoveMyCar), dlgt);
     
        }
     
        // process request
        void RemoveMyCar (IAsyncResult ar) 
        {
           // remove the car
           Remove dlgt      = ar.AsyncState as Remove;
     
           NulData response = dlgt.EndInvoke (ar);
     
           if (response.State != State.Ok) 
           {
              System.Console ("Unable to remove my car: " + car.Id);
              return;
           }
        }
    

Invoking AfArch# using the synchronous way

The first one method is clear and very straightforward. You make a request using directly the API provided by the C# binding and then your program gets blocked until request response arrives. Once request answer has arrived, the program check if the car have been actually removed.

The main problem of the first method is that it blocks your program. If your program is a Gtk# application (or some gui# which is not thread-driven) you have a problem because your interface will get hanged until request reply arrives.

There are another problem with this aproach. Af-Arch framework provides you with a session mechanism which allows you to invalidate running user session (because the user haven't make a request for a long time) and define a callback which will be run to ask the user for the new password.

Inside the previous context, during the session refresh process, all your pending request are stopped until a valid session can be obtained throught the previous callback. Because your program is hanged at the reply, the Af-Arch framework will not be able to notify your program that user's session has expired.

Invoking AfArch# using the asynchronous way

Of course, the second method stand for the previous problem. As a side effect it has a litle bit confusing interface.

The second method, which is actually supported by the .NET VM and not by any Af-Arch support, separates the request from its process. This is pretty much like the Af-Arch interface while using C.

The first step is done by creating a delegate from the API we want to request. Then we use the BeginInvoke method passing in all arguments needed by the method following the two compulsory arguments: the callback to process the delegate termination and the delegate reference itself.

At this point you may be asking why I have to pass in the delegate which I actually using to invoke the BeginInvoke method? That is a good question. .NET asynchronous invoke API was designed this way and you have to provide as the last argument the delegate reference itself.

Note the method signatures for the request method:

       void RemoveMyCar ()     

and the request process method:

       void RemoveMyCar (IAsyncResult ar)

It is not important to have the same method names. Actually .NET uses the method signatures to invoke the correct method at the correct time.

Once the request have been received, to get request result, the steps, described at the example above, must be followed.

Using the last method you can actually receive, at any time, a session refresh request from Af-Arch framework or to make several request, keeping on other computational task or updating your program interface, until get the request answer from remote Af-Arch server.

Calling BeginInvoke for a delegate which receives parameters

All parameters that have to be passed to the delegate being handled by BeginInvoke method must be passed in to BeginInvoke method followed by the ASyncCallback callback and the deletagate.

      // We want to perform a list request
      GetList list = new GetList (Cars.GetList);

      // begin invocation. GetList method receives two integer parameters
      // We pass them to the following function.
      list.BeginInvoke (0, 0, new AsyncCallback (CarList), list);

Services delegates declarations

Actually, delegates declarations to encapsulate Af-Arch# services can be found at AfArch.AfDal packages.

Connecting AfArch# with Gtk# using the asynchronous way

If your program doesn't makes use of the asynchronous interface while using Gtk# (I don't recomend this type of application design) you won't have any additional problem.

If your Gtk# application makes use of Threads and you are getting a:

      Xlib: unexpected async reply (sequence 0x10e6b)!

or maybe it simply get hanged when request response have been received, it is posible you are operating Gtk# directly from a Thread which is not the main one.

Actually the AfArch# binding have been heavy tested under Mono platform. In fact, all developers I know uses AfArch# + Gtk# + Mono.

The very first thing you have to know about Gtk# is that it doesn't mix well with Threads. It doesn't means you can't use thread to program your Gtk# applications. But means Gtk# doesn't allows you to operate directly the Gtk# interface from another Thread than the main one.

This main thread is actually the one who have called Application.Init () method.

While using AfArch# with Gtk#, you can directly operate the interface as we have said. But you need a method which allows you to operate Gtk# interface in a safe way. This is done by using the ThreadNotify helper class which comes with Gtk# distribution.

Here is an example on how to use ThreadNotify:

    public NulData response;
    static ThreadNotify notify;
    
    // launch async request 
    void RemoveMyCar () 
    {
 
       // create the delegate
       Remove dlgt = new Remove (car.Remove);
 
       // prepare gtk notify function
       notify      = new ThreadNotify (new ReadyEvent (RemoveMyCarGtk));
 
       // invoke the delegate so the .NET VM creates a new
       // thread which actually runs my request
       dlgt.BeginInvoke (new AsyncCallback (RemoveMyCar), dlgt);
 
    }
 
    // process request
    void RemoveMyCar (IAsyncResult ar) 
    {
       // remove the car
       Remove dlgt      = ar.AsyncState as Remove;
       response         = dlgt.EndInvoke (ar);
 
       // notify gtk to execute our method
       notify.WakeupMain ();
    }
 
    // operate gtk
    void RemoveMyCarGtk () 
    {
       // we can safely operate gtk# inside this notifier
       if (response.State != State.Ok) 
       {
          System.Console ("Unable to remove my car: " + car.Id);
          return;
       }
    }
Note that programing Gtk# using Async interface needs to use 3 steps.
  1. The first step, actually inside the Gtk# main loop, your application arms the delegates, the GTK# notifier and launch the request.

  2. The second step you receive the AfArch response. Instead of directly process the response and manipulate the Gtk# interface your application notifies Gtk# to include inside its "pending tasks" your method RemoveMyCarGtk.

  3. On the thrid step, eventually the Gtk# main loop will execute your Method so your method can safely modify the interface.

Making more easily to use Gtk# with Af-Arch#

As we have saw, programing Gtk# using the Asynchronous interface for every method your application invoke is a litle bit complex. This is because we have to program 3 method in order to be able to produce a request and safely modify the interface.

Af-Arch# provides a namespace to allow making service invocation more easily: AfArch.AfDal.Gtk.

Here is an example on how to invoke remove services as previous examples using AfArch.AfDal.Gtk class:

     // launch async request 
     void RemoveMyCar () 
     {
  
        // launch request to remove the given car
        new AfDalInvokeRemove (new Remove (car.Remove), 
                               new InvokeHandler (RemoveMyCar));

        // keep on doing other computational work
     }
  
     // process request
     void RemoveMyCar (NulData response) 
     {
        // we can modify Gtk# interface from this method
        // because it is being run inside the Gtk# main loop.

        if (response.State != State.Ok) 
        {
           System.Console ("Unable to remove my car: " + car.Id);
           return;
        }
        
     }

Note the signature for the request process method:

     void RemoveMyCar (NulData response) 

This process function directly receives the request result rather than an AsyncResult object.

The main advantaje is that request process method execute inside the Gtk# main loop, allowing process method to modify Gtk# interface, while the code written keeps clean and maintainable.