Skip to content

Blocking and Non-blocking APIs

Most of Backendless APIs for .NET are available as synchronous (blocking) and asynchronous (non-blocking) implementations. The synchronous (blocking APIs) block the execution of the thread where they are called until a result is received from the server. The asynchronous (non-blocking) APIs do block, the program can continue its execution.

The asynchronous (non-blocking) APIs are available in two formats:

  1. Methods with a callback argument. The argument contains two delegate methods, one to receive the result for a successful API invocation and another to receive an error if it is returned by the server. The API methods with the callback argument always have AsyncCallback<T> in the method declaration. Usually it is the last argument in a signature:

    Backendless.UserService.Register( user, new AsyncCallback<BackendlessUser>( 
        registeredUser =>
        {
          Console.WriteLine( $"User has been registered. " + 
                             $"User's object ID - {registeredUser.ObjectId}" );   
        },
        error =>
        {
           Console.WriteLine( $"Server reported an error - {error.Message}"); 
        }));
    

  2. Methods marked with the async keyword. The return type of these methods is either System.Threading.Tasks.Task or System.Threading.Tasks.Task<some-type> and the method names always end with Async. Since the async and await keywords were introduced in .NET 4.5, these methods are available in the target frameworks 4.5 and above.

    Task<BackendlessUser> task = Backendless.UserService.RegisterAsync( user );
    

For the first format of the asynchronous APIs (the ones with the AsyncCallback<T> argument), the class has the following declaration:

using BackendlessAPI.Exception;

namespace BackendlessAPI.Async
{
  public delegate void ErrorHandler( BackendlessFault _backendlessFault );
  public delegate void ResponseHandler<T>( T response );

  public class AsyncCallback<T>
  {
    internal ErrorHandler ErrorHandler;
    internal ResponseHandler<T> ResponseHandler;

    public AsyncCallback( ResponseHandler<T> responseHandler, ErrorHandler errorHandler )
    {
      this.ResponseHandler = responseHandler;
      this.ErrorHandler = errorHandler;
    }
  }
}

where the ResponseHandler<T>( T response )delegate is called when a response for an asynchronous operation is available. If operation results in an error, it is delivered to the ErrorHandler delegate. See the Error Handling section for additional information on how to process errors.