Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registering Native and RTD based Async functions #17

Open
ateene opened this issue Feb 6, 2018 · 0 comments
Open

Registering Native and RTD based Async functions #17

ateene opened this issue Feb 6, 2018 · 0 comments

Comments

@ateene
Copy link

ateene commented Feb 6, 2018

The order of the ExcelRegistion statement needs to be different for registering RTD or Native async functions.

case #1

Here is my example that works for registering RTD async functions and what I think the wrapped functions look like. In this case all three async functions work as expected with the dnaDelayedTaskHello working as RTD based async function, and the postAsyncReturnConfig works for both the dnaDelayedTaskHello and dnaRtdWrapped functions, returning #GETTING_DATA while processing.

using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using ExcelDna.Integration;
using ExcelDna.Registration;
using ExcelDna.Registration.Utils;
using ExcelDna.IntelliSense;

namespace ExcelDnaRegistration
{
public class AddIn : IExcelAddIn
{
public void AutoOpen()
{
// Register Funtion settings
var postAsyncReturnConfig = GetPostAsyncReturnConversionConfig();
ExcelRegistration.GetExcelFunctions()
.ProcessAsyncRegistrations(nativeAsyncIfAvailable: false)
.ProcessParameterConversions(postAsyncReturnConfig)
.RegisterFunctions();

        // Intellinse Sense
        IntelliSenseServer.Register();
    }
    
    public void AutoClose()
    {
    }
    
    static ParameterConversionConfiguration GetPostAsyncReturnConversionConfig()
    {
        // This conversion replaces the default #N/A return value of async functions with the #GETTING_DATA value.
        var rval = ExcelError.ExcelErrorGettingData;
        return new ParameterConversionConfiguration()
            .AddReturnConversion((type, customAttributes) => type != typeof(object) ? null : ((Expression<Func<object, object>>)
                                            ((object returnValue) => returnValue.Equals(ExcelError.ExcelErrorNA) ? rval : returnValue)));
    }
}

public class Functions
{
    // .NET 4.5 function with async/await
    [ExcelAsyncFunction(Description = "Excel Dna Async Test")]
    public static async Task<string> dnaDelayedTaskHello(
        [ExcelArgument(Name = "name")] string name,
        [ExcelArgument(Name = "delay(ms)")] int msDelay)
    {
        await Task.Delay(msDelay);
        return $"Hello {name}";
    }

    // This is what I think the generated RTD based Task wrappers looks like.
    [ExcelFunction]
    public static object dnaRtdWrapper(string name, int msDelay)
    {
        return AsyncTaskUtil.RunTask("dnaExplicitWrap", new object[] { name, msDelay }, () => dnaDelayedTaskHello(name, msDelay));
    }

    // This is what I think the generated Native based async wrapper looks like
    [ExcelFunction]
    public static void dnaNativeWrapper(string name, int msDelay, ExcelAsyncHandle asyncHandle)
    {
        NativeAsyncTaskUtil.RunTask(() => dnaDelayedTaskHello(name, msDelay), asyncHandle);
    }
}

}

case #2

When I make the following change for registering Native async functions

ExcelRegistration.GetExcelFunctions()
.ProcessAsyncRegistrations(nativeAsyncIfAvailable: true)
.ProcessParameterConversions(postAsyncReturnConfig)
.RegisterFunctions();

I get a System.ArgumentOutOfRangeException error for the ExcelRegistraion statement

case #3

I can fix this by changing the order of statement to the following, then all three async functions work as expected. The dnaDelayedTaskHello works as Native async function

ExcelRegistration.GetExcelFunctions()
            .ProcessParameterConversions(postAsyncReturnConfig)
            .ProcessAsyncRegistrations(nativeAsyncIfAvailable: true)
            .RegisterFunctions();

case #4

When I switch back to the nativeAsyncIfAvable back to false keeping the same order

ExcelRegistration.GetExcelFunctions()
.ProcessParameterConversions(postAsyncReturnConfig)
.ProcessAsyncRegistrations(nativeAsyncIfAvailable: false)
.RegisterFunctions();

All three async function work, however the postAsyncReturnConfig does not work for the dnaDelayTaskHello function (it still returns the #N/A while processing), whereas the dnaRtdWrapper does return the #GETTIN_DATA while processing.

So It looks like I have to case #1 for registering RTD async functions and case #3 for registering Native async functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant