-
Hello msedge_D5Fbdwqkdu.mp4App script code function RHSOLUTIONS(query) {
var url = < API PATH >;
var response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
var json = response.getContentText();
var data = JSON.parse(json);
var result = data[0].id + " " + data[0].name;
Logger.log(result);
return result;
} This is demonstration of Excel function for same thing. explorer_TL2D7lEUub.mp4It takes 1 minute longer for just ~80 cells How I implement this public sealed class RhSolutionsAddIn : IExcelAddIn
{
public static ServiceProvider ServiceProvider { get; private set; }
public void AutoOpen()
{
IServiceCollection Services = new ServiceCollection();
// Add HttpClient, MemoryCache and DB client
Services.AddHttpClient()
.AddMemoryCache()
.AddSingleton<IDatabaseClient, DatabaseClient>();
ServiceProvider = Services.BuildServiceProvider();
ServicePointManager.SecurityProtocol =
SecurityProtocolType.Tls12;
}
public void AutoClose()
{
}
} using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace RhSolutions.Services;
public class DatabaseClient : IDatabaseClient
{
private readonly HttpClient _httpClient;
private readonly IMemoryCache _memoryCache;
public HttpStatusCode StatusCode { get; private set; }
public DatabaseClient(HttpClient httpClient, IMemoryCache memoryCache)
{
_httpClient = httpClient;
_memoryCache = memoryCache;
}
public async Task<IEnumerable<Product>> GetProducts(string query)
{
UriBuilder builder = new(<API placeholder>)
{
Query = $"query={query}"
};
string request = builder.Uri.AbsoluteUri;
if (!_memoryCache.TryGetValue(line, out IEnumerable<Product> products))
{
var response = await _httpClient.GetAsync(request);
try
{
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
products = JsonConvert.DeserializeObject<IEnumerable<Product>>(json) ?? Enumerable.Empty<Product>();
}
catch
{
StatusCode = response.StatusCode;
return Enumerable.Empty<Product>();
}
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromHours(1));
_memoryCache.Set(query, products, cacheEntryOptions);
if (products.Any())
{
_memoryCache.Set(products.First(), products, cacheEntryOptions);
}
return products;
}
else
{
return products;
}
}
} [ExcelFunction]
public static object RHSOLUTIONS(string query)
{
if (ExcelAsyncUtil.Run(nameof(RHSOLUTIONS), query, delegate
{
return databaseClient.GetProducts(line)
.GetAwaiter()
.GetResult();
}) is not IEnumerable<Product> requestResult)
{
return "Загрузка...";
}
else
{
if (!requestResult.Any())
{
return ExcelError.ExcelErrorNA;
}
else
{
var firstProduct = requestResult.First();
return $"{firstProduct.ProductSku} {firstProduct.Name}";
}
}
} Any tips how to improve this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
There are a few things you can do to improve the performance in the Excel / Excel-DNA side. But I suspect the biggest problem is in the number of concurrent calls made through the HttpClient. So, the first thing to try is to make sure you are setting the I presume you are targeting .NET Framework 4.x - I think the default value is 2 and you would set it like this, maybe in your AutoOpen?
There's also a way to set it per url:
Under .NET 6 I think the code might be different:
In any case, that would be the first focus - determine what the connection limit is and try to log or figure out how many concurrent connections are being made. This might also be limited by the server, but your Google example indicates this is not the bottleneck. Some more ideas for optimization (each of these are independent, and might make a small difference:
This should get you to a function with similar performance to the Google sheet function. Now there are some more improvement ideas:
Please write back to say what you try and how it works out :-) |
Beta Was this translation helpful? Give feedback.
-
@govert, thank you! |
Beta Was this translation helpful? Give feedback.
There are a few things you can do to improve the performance in the Excel / Excel-DNA side. But I suspect the biggest problem is in the number of concurrent calls made through the HttpClient.
So, the first thing to try is to make sure you are setting the
maxConcurrentConnections
for the HttpClient. This depends on whether you are targeting .NET Framework 4.x or .NET 6. You should also Google about this a bit.I presume you are targeting .NET Framework 4.x - I think the default value is 2 and you would set it like this, maybe in your AutoOpen?