Skip to main content

.NET (C# / VBA.NET): arupcompute-connect-dotnet

tip

There is no project charging for use of ArupCompute, however project usage data is critical to justifying continued funding of ArupCompute - please provide a job number!

To contribute and / or submit bug reports go to the arupcompute-connect-dotnet github.

NOTE

You will require access to the Arup GitHub account to see the above link. If you are having trouble reach out on the ArupCompute teams.

You can join the teams using the code b53lq6l

Installation

You can reference the arupcompute-connect-dotnet library using NuGet, dotnet, or Visual Studio.

Dotnet

As arupcompute-connect-dotnet is hosted on a private feed you will need to install the Azure Artifacts Credential Provider.

Also ensure that you visit this webpage to ensure that you have access to the repository where the reference libraries are stored (enter Arup login details if prompted).

Project setup

Add a nuget.config file to your project, in the same folder as your .csproj or .sln file

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="arupcomputedevops@Release" value="https://pkgs.dev.azure.com/arupcomputedevops/_packaging/arupcomputedevops/nuget/v3/index.json" />
</packageSources>
</configuration>

Add references

Use the dotnet add package --interactive command (using the interactive flag, which allows the credential manager to prompt you for credentials):

dotnet add [<PROJECT>] package --interactive arupcompute-connect-dotnet

The three packages you will need to add to your solution are:

  • arupcompute-connect-dotnet
  • Arup.Compute.Models
  • Arup.Compute.DotNetSdk

Restore packages

If prompted to restore packages you may need to use the --interactive flag:

dotnet restore --interactive

Simple example

using Arup.Compute.Connect;
using Arup.Compute.Models;
using Arup.Compute.DotNetSdk;
using System.Threading.Tasks;
Connection connection = new Connection("00000-00"); // The job number will _not_ be charged
int calcId = 11416564; // Sample Library - Basic calculation

Dictionary<string, object> inputs = new Dictionary<string, object>()
{
{ "a", 1 },
{ "b", 2}
};

Task<CalcRecord> resultTask = Call.ExecuteCalculationAsync(connection, calcId, false, inputs);

CalcRecord calcRecord = resultTask.Result;

If you are interacting with a library that utilises the expanded features of ArupCompute (e.g. report writing, errors, warnings, remarks etc.) such as DesignCheck2 you will need the additional step below to interpret the .Result:

Task<CalcRecord> resultTask = Call.ExecuteCalculationAsync(connection, calcId, false, inputs, resultType: Arup.Compute.Connect.Call.ResultType.Simple); // Simple provides reports, errors etc. default is mini which just returns results
CalcRecord result = resultTask.Result;
ArupComputeResult acr = result.ParseOutput<Arup.Compute.DotNetSdk.ArupComputeResult>();

// For example if you want access to the plain-text report
string report = acr.ArupComputeReport;

If you are utilising the batch execution feature of ArupCompute and want access to reports etc. you will need to do the following:

///Call.ExecuteBatchCalculationAsync(...)
var lacr = result.ParseOutput<List<Arup.Compute.DotNetSdk.ArupComputeResult>>();

Non-primitive inputs / outputs - JSON

The recommended library for working with JSON in C# is Newtonsoft.JSON. However, the arupcompute-connect-dotnet library uses this in the background and can deal with serialisation / deserialisation for you.

Parallel Mode

When making calls to AC Local you can use "parallel mode" to run a batch of calcs. This will make AC Local run the calculations in the batch in parallel, meaning that the batch will run faster. There is additional setup time required on AC Local when running calcs in parallel, so for small batches it is better to run the batch not in parallel mode. From testing we have found that if the batch is larger than 10 calcs then running in parallel will be faster than in regular batch mode.

To run a calc in parallel, set the parallel param in Call.ExecuteCalculationAsync to true.

Connection connection = new Connection("00000-00"); // The job number will _not_ be charged
int calcId = 11416564; // Sample Library - Basic calculation

Dictionary<string, object> inputs = new Dictionary<string, object>()
{
{ "a", new List<int>() { 1, 2, 3, 4, 5 } },
{ "b", new List<int>() { 2, 3, 4, 5, 6 } }
};

Task<CalcRecord> resultTask = Call.ExecuteCalculationAsync(connection, calcId, batch: true, inputs, parallel: true); // Note: parallel and batch are set to true

CalcRecord calcRecord = resultTask.Result;
useFanOut

parallel should not be set to True at the same time as useFanOut. Doing this would mean that parallel would have no effect

Optional Inputs

When you want to use the default value for an optional input you can either set the value of the input to be null, or leave out the input entirely from your inputs dictionary:

// for single invocation

Dictionary<string, object> inputs = new Dictionary<string, object>()
{
{ "a", 1 },
{ "b", 2 },
{ "optional-input", null } // or leave out this line
};

Task<CalcRecord> resultTask = Call.ExecuteCalculationAsync(connection, calcId, batch: false, inputs);

CalcRecord calcRecord = resultTask.Result;
// for batch call

Dictionary<string, object> inputs = new Dictionary<string, object>()
{
{ "a", new List<int>() { 1, 2, 3, 4, 5 } },
{ "b", new List<int>() { 2, 3, 4, 5, 6 } },
{ "optional-input", new List<object>() { null, 3, 4, 1 } } // NOTE: This list is not as long as the above two lists
};

Task<CalcRecord> resultTask = Call.ExecuteCalculationAsync(connection, calcId, batch: true, inputs);

CalcRecord calcRecord = resultTask.Result;