Asynchronous Calls (.NET)

Invoking methods asynchronously in RO .NET is quite easy and in contrast to the Delphi approach, it doesn't require a special kind of interface. The code for the async interface and the async proxy will be automatically generated during the creation of the interface files.

For example, when creating a similar service called MyService with a Sum operation, the interface file will contain an async interface and an async proxy, like the following:

public interface IMyService_Async : RemObjects.SDK.IROService_Async
{
  System.IAsyncResult BeginSum(int A, int B, System.AsyncCallback @__Callback, object @__UserData);
  int EndSum(System.IAsyncResult @__AsyncResult);
}
public partial class MyService_AsyncProxy : RemObjects.SDK.AsyncProxy, IMyService_Async
{
  public MyService_AsyncProxy(IMessage aMessage, IClientChannel aClientChannel) : base(aMessage, aClientChannel){} 
...
}

So on the client side, you just need to create an instance of your async proxy object:

IMyService_Async fMyService = new MyService_AsyncProxy(message, clientChannel);

and then call the BeginSum method:

fMyService.BeginSum(
  AValue, BValue,
  lAsyncResult =>
  {
    int lResult = fMyService.EndSum(lAsyncResult);
    MessageBox.Show(String.Format("Result is: {0}", lResult)); 
  }
  , null);

Let's take a look at the fMyService.BeginSum method above:

Since we called the method asynchronously, we should pass a reference to the callback function that will recieve and correctly process the result. In the sample above, we've used this approach with lambdas, since it's shorter and clearer, but you can actually use approaches with anonymous methods like the following:

fMyService.BeginSum(
  AValue, BValue,
  delegate(IAsyncResult lAsyncResult)
  {
    int lResult = fMyService.EndSum(lAsyncResult);
    MessageBox.Show(String.Format("Result is: {0}", lResult));
  }
  , null);

or create a delegate explicitly like this:

public void ResultCb(IAsyncResult aAsyncResult)
{
  int lResult = fMyService.EndSum(aAsyncResult);
  MessageBox.Show(String.Format("Result is: {0}", lResult));
}

private void btnCallAsync_Click(object sender, EventArgs e)
{
  fMyService.BeginSum(
    AValue, BValue,
    new AsyncCallback(ResultCb),
    null);
}

Also please note that when you are using asynchronous calls, you will get the results NOT in the main thread of your application, so if you need to reflect the result in GUI, you will need to dispatch it to the main thread that is managing all GUI controls.

In the sample below we show the result of the sum operation in the textbox on the main form:

// declare delegate
public delegate void UpdateGuiCallback(Int32 aResult);

// our callback function
public void UpdateGuiCb(Int32 aResult)
{
  txtResult.Text = aResult.ToString();
}

private void btnCallAsync_Click(object sender, EventArgs e)
{
  int AVal = Convert.ToInt32(AValue.Value);
  int BVal = Convert.ToInt32(BValue.Value);

  fMyService.BeginSum(AVal, BVal,
    lAsyncResult =>
    {
      int lResult = fMyService.EndSum(lAsyncResult);
      MessageBox.Show(String.Format("Result is: {0}", lResult));

      // Dispatch to the main thread to update result textbox
      this.Invoke(new UpdateGuiCallback(UpdateGuiCb), new Object[] { lResult });
    }, 
    null);
}