.NET (C# / VBA.NET): arupcompute-connect-dotnet
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.
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;