Я создал приложение с изолированной функцией .net 8 в качестве POC для использования устойчивых объектов, содержащих один объект. Также созданы 2 конечные точки: одна для получения значения сущности, другая для воздействия на сущность. При получении значения сущности оно всегда равно нулю. Я оставил приложение работать на ночь, чтобы проверить, не является ли это проблемой времени, и значение по-прежнему возвращается как нулевое. Я пробовал это как на Azureite, так и на учетной записи хранения в Azure.
Функция сущности распознается платформой, но точка останова внутри функции никогда не достигается.
Код ниже взят непосредственно из документации MS по Durable Entities. здесь
Определение сущности:
public class Counter : TaskEntity<int>
{
readonly ILogger logger;
public Counter(ILogger<Counter> logger)
{
this.logger = logger;
}
public void Add(int amount)
{
this.State += amount;
}
public Task Reset()
{
this.State = 0;
return Task.CompletedTask;
}
public Task<int> Get()
{
return Task.FromResult(this.State);
}
// Delete is implicitly defined when defining an entity this way
[Function(nameof(Counter))]
public static Task Run([EntityTrigger] TaskEntityDispatcher dispatcher)
=> dispatcher.DispatchAsync<Counter>();
}
Определения функций:
[Function("GetCounter")]
public static async Task<HttpResponseData> GetCounter(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "Counter/{entityKey}")] HttpRequestData req,
[DurableClient] DurableTaskClient client, string entityKey)
{
var entityId = new EntityInstanceId("Counter", entityKey);
EntityMetadata<int>? entity = await client.Entities.GetEntityAsync<int>(entityId);
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync(entity?.State);
return response;
}
[Function("AddCounter")]
public static async Task<HttpResponseData> AddCounter(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "Counter/{entityKey}/add")] HttpRequestData req,
[DurableClient] DurableTaskClient client, string entityKey)
{
var entityId = new EntityInstanceId("Counter", entityKey);
await client.Entities.SignalEntityAsync(entityId, "add", 1);
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
return response;
}
csproj-файл:
<Project Sdk = "Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include = "Microsoft.AspNetCore.App" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker" Version = "1.21.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version = "1.1.3" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Extensions.Http" Version = "3.1.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version = "1.2.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Sdk" Version = "1.17.0" />
<PackageReference Include = "Microsoft.ApplicationInsights.WorkerService" Version = "2.22.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.ApplicationInsights" Version = "1.2.0" />
</ItemGroup>
<ItemGroup>
<None Update = "host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update = "local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include = "System.Threading.ExecutionContext" Alias = "ExecutionContext" />
</ItemGroup>
</Project>
у меня ваш код работает нормально. addcounter , getcounter , run
Я не думаю, что это актуально, но мне просто интересно, почему у вас есть get в качестве метода для вашей функции Add? Клиенты будут ожидать, что get будет идемпотентным, а не что-то мутировать.
@VivekVaibhavShandilya Я обращаюсь к объекту с помощью DurableTaskClient через HTTP-вызов.
@VivekVaibhavShandilya вы используете как приложение с изолированными функциями .net 8?
@EvanNielsen Просто подтверждаю, что вы получаете доступ к объекту в другом Http-вызове вместо прямого вызова URL-адреса объекта?
@EvanNielsen да
@VivekVaibhavShandilya Я получаю доступ к объекту через тот же URL-адрес, который вы используете на своих скриншотах. Можете ли вы сказать мне, какую версию Visual Studio и какую версию Function Core Tools вы используете?
@EvanNielsen Версия Visual Studio — 17.10.0, версия основных инструментов: 4.0.5801, версия среды выполнения функций: 4.34.1.22669 i.imgur.com/1X2nDcz.png
@EvanNielsen Перекрестная проверка, разрешен http-запрос или нет. Проверьте, не блокирует ли какой-нибудь брандмауэр?
@VivekVaibhavShandilya Я обновил VS и основные инструменты до той же версии, которую вы используете, и имею ту же версию среды выполнения функций, но все равно безуспешно. Доступ к объекту через конечную точку http всегда возвращает значение null. Брандмауэр не блокирует. Не могли бы вы прислать версии пакетов nuget, которые вы используете?
@EvanNielsen, не могли бы вы добавить интересующий вас файл .csproj?
@VivekVaibhavShandilya Я обновил пост с помощью csproj
@EvanNielsen Я использую DurableTask версии 1.1.1.
Проблема с Github: github.com/Azure/azure-functions-durable-extension/issues/2830


У меня ваш код работал нормально.
Как я уже упоминал в комментарии, я использую DurableTask Версию 1.1.1.
Я попробовал использовать 1.1.3 и тоже столкнулся с подобной проблемой. Это связано с поддержкой пакетов другими пакетами.
Я также пробовал обновить другие пакеты, но все они выдают ошибку. Пакеты несовместимы друг с другом.
Я бы предложил использовать 1.1.1 или 1.1.2 с этими версиями других пакетов.
Это сработало для меня.
Function.cs:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Client;
using Microsoft.DurableTask.Client.Entities;
using Microsoft.DurableTask.Entities;
using Microsoft.Extensions.Logging;
using System.Net;
namespace FunctionApp9
{
public static class Function1
{
[Function("GetCounter")]
public static async Task<HttpResponseData> GetCounter(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "Counter/{entityKey}")] HttpRequestData req,
[DurableClient] DurableTaskClient client, string entityKey)
{
var entityId = new EntityInstanceId("Counter", entityKey);
EntityMetadata<int>? entity = await client.Entities.GetEntityAsync<int>(entityId);
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync(entity?.State);
return response;
}
[Function("AddCounter")]
public static async Task<HttpResponseData> AddCounter(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "Counter/{entityKey}/add")] HttpRequestData req,
[DurableClient] DurableTaskClient client, string entityKey)
{
var entityId = new EntityInstanceId("Counter", entityKey);
await client.Entities.SignalEntityAsync(entityId, "add", 1);
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
return response;
}
}
public class Counter : TaskEntity<int>
{
readonly ILogger logger;
public Counter(ILogger<Counter> logger)
{
this.logger = logger;
}
public void Add(int amount)
{
this.State += amount;
}
public Task Reset()
{
this.State = 0;
return Task.CompletedTask;
}
public Task<int> Get()
{
return Task.FromResult(this.State);
}
// Delete is implicitly defined when defining an entity this way
[Function(nameof(Counter))]
public static Task Run([EntityTrigger] TaskEntityDispatcher dispatcher)
=> dispatcher.DispatchAsync<Counter>();
}
}
FunctionApp9.csproj:
<Project Sdk = "Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include = "Microsoft.AspNetCore.App" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker" Version = "1.21.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version = "1.1.2" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Extensions.Http" Version = "3.1.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version = "1.2.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.Sdk" Version = "1.17.2" />
<PackageReference Include = "Microsoft.ApplicationInsights.WorkerService" Version = "2.22.0" />
<PackageReference Include = "Microsoft.Azure.Functions.Worker.ApplicationInsights" Version = "1.2.0" />
</ItemGroup>
<ItemGroup>
<None Update = "host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update = "local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include = "System.Threading.ExecutionContext" Alias = "ExecutionContext" />
</ItemGroup>
</Project>
OUTPUT:Кажется, это исправлено в Microsoft.Azure.Functions.Worker.Extensions.DurableTask версии 1.1.4.
Вы получаете доступ к объекту в своем клиенте?