Search code examples
c#asynchronousexcel-dna

Queuing Async Function Calls


I am using Excel-DNA to run asynchronous excel function calls. My excel function calls R via a comm interface.

As I understand it the comm interface cannot be called asynchronously, and it has to be called synchronously. I am afraid that internal states on the R side might screw this process up and therefore I would like to have an explicit control over when the excel functions are being run.

How can I create a queue and only run the excel functions one at a time i.e. as soon as one is ready then I start running the other function.

And YES I do want to run the excel functions asynchronously since it stops the excel session from being freezed. I do understand that I do not gain any speed by doing this, but it "feels faster" for the user.

Here is my sample code:

    [ExcelFunction]
    public static object AsyncRCallTest(int a1, int a2)
    {
        return ExcelAsyncUtil.Run("ASyncRCallTest", new object[] { a1, a2 }, delegate
        {
            try
            {
                var a = RConnection.Evaluate(a1);
                var b = RConnection.Evaluate(a2);
                return a + b;
            }
            catch (Exception err)
            {
                return err.Message;
            }
        });
    }

Solution

  • [MethodImpl(MethodImplOptions.Synchronized)] seemed to do the trick (see sample code below). I would be glad if someone could verify this.

        [ExcelFunction]
        public static object AsyncRCallTest(int a1, int a2)
        {
            return ExcelAsyncUtil.Run("AsyncRCallTest", new object[] { a1, a2 }, delegate
            {
                return SyncRCallTest(a1, a2);
            });
        }
    
    
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static object SyncRCallTest(int a1, int a2)
        {
    
            try
            {
                var a = RConnection.Evaluate(a1);
                var b = RConnection.Evaluate(a2);
                return a + b;
            }
            catch (Exception err)
            {
                return err.Message;
            }
    
        }