Обучение
Модуль
Создание первого приложения Орлеана с помощью ASP.NET Core 8.0 - Training
Узнайте, как создавать облачные распределенные приложения с помощью Орлеана.
Этот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
перед написанием кода для реализации класса граней создайте новый проект библиотеки классов, предназначенный для .NET Standard или .Net Core (предпочтительно) или платформа .NET Framework 4.6.1 или более поздней версии (если вы не можете использовать .NET Standard или .net Core из-за зависимостей). Многогранные интерфейсы и классы граней могут быть определены в одном проекте библиотеки классов или в двух разных проектах для лучшего разделения интерфейсов от реализации. в любом случае проекты должны ссылаться на microsoft. Orleans. Core. абстракции и microsoft. Orleans. CodeGenerator. MSBuild NuGet пакетах.
более подробные инструкции см. в разделе Project Setupучебника 1 – Orleans основы.
Грани взаимодействуют друг с другом и вызываются извне, вызывая методы, объявленные как часть соответствующих интерфейсов детализации. Класс граней реализует один или несколько ранее объявленных интерфейсов граней. Все методы многогранного интерфейса должны возвращать Task (для void
методов), или ValueTask<TResult> (для методов, Task<TResult> возвращающих значения типа T
).
Ниже приведен фрагмент кода из примера службы присутствия Orleans версии 1,5:
public interface IPlayerGrain : IGrainWithGuidKey
{
Task<IGameGrain> GetCurrentGame();
Task JoinGame(IGameGrain game);
Task LeaveGame(IGameGrain game);
}
public class PlayerGrain : Grain, IPlayerGrain
{
private IGameGrain _currentGame;
// Game the player is currently in. May be null.
public Task<IGameGrain> GetCurrentGame()
{
return Task.FromResult(_currentGame);
}
// Game grain calls this method to notify that the player has joined the game.
public Task JoinGame(IGameGrain game)
{
_currentGame = game;
Console.WriteLine(
$"Player {GetPrimaryKey()} joined game {game.GetPrimaryKey()}");
return Task.CompletedTask;
}
// Game grain calls this method to notify that the player has left the game.
public Task LeaveGame(IGameGrain game)
{
_currentGame = null;
Console.WriteLine(
$"Player {GetPrimaryKey()} left game {game.GetPrimaryKey()}");
return Task.CompletedTask;
}
}
Метод детализации, возвращающий значение типа T
, определяется в интерфейсе с детализацией в виде возвращаемого Task<T>
значения.
Для методов детализации, не помеченных async
ключевым словом, если возвращаемое значение доступно, оно обычно возвращается с помощью следующей инструкции:
public Task<SomeType> GrainMethod1()
{
return Task.FromResult(GetSomeType());
}
Метод детализации, который не возвращает значения, фактически является методом void, определяется в интерфейсе с детализацией как возвращающий Task
. Возвращаемое Task
значение указывает на асинхронное выполнение и завершение метода. Для методов детализации, не помеченных async
ключевым словом, когда метод "void" завершает свое выполнение, он должен вернуть специальное значение Task.CompletedTask :
public Task GrainMethod2()
{
return Task.CompletedTask;
}
Метод детализации, помеченный как, async
возвращает значение напрямую:
public async Task<SomeType> GrainMethod3()
{
return await GetSomeTypeAsync();
}
void
Метод детализации, помеченный как async
, не возвращающий значение, просто возвращается в конце выполнения:
public async Task GrainMethod4()
{
return;
}
Если метод детализации получает возвращаемое значение от другого вызова асинхронного метода, в Гране или нет, и не требует выполнения обработки ошибок этого вызова, он может просто вернуть Task
полученное из этого асинхронного вызова.
public Task<SomeType> GrainMethod5()
{
Task<SomeType> task = CallToAnotherGrain();
return task;
}
void
Аналогичным образом метод детализации может вернуть возвращаемое значение Task
в другой вызов, а не ожидать его.
public Task GrainMethod6()
{
Task task = CallToAsyncAPI();
return task;
}
ValueTask<T>
можно использовать вместо Task<T>
.
Ссылка детализации — это прокси-объект, реализующий тот же интерфейс гранулярности, что и соответствующий класс граней. Он инкапсулирует логическое удостоверение (тип и уникальный ключ) целевого Грана. Ссылка на детализацию используется для вызова детализации целевого объекта. Каждый детализированный справочник — это один экземпляр класса граней (один и тот же), но он может создавать несколько независимых ссылок на один и тот же детализацию.
Так как ссылка на детализацию представляет логическую идентификацию целевого объекта, она не зависит от физического расположения граней и остается действительной даже после полного перезапуска системы. Разработчики могут использовать детализированные ссылки, такие как любой другой объект .NET. Он может быть передан в метод, использован в качестве возвращаемого значения метода и т. п. и даже сохранен в постоянное хранилище.
Ссылку на детализацию можно получить, передав идентификатор детализации в IGrainFactory.GetGrain<TGrainInterface>(Type, Guid) метод, где T
является интерфейсом граней и key
является уникальным ключом детализации в типе.
Ниже приведены примеры того, как получить ссылку на детализацию для интерфейса, IPlayerGrain
определенного выше.
Внутри класса граней:
IPlayerGrain player = GrainFactory.GetGrain<IPlayerGrain>(playerId);
Из кода клиента Orleans.
IPlayerGrain player = client.GetGrain<IPlayerGrain>(playerId);
Модель программирования Orleans основана на асинхронном программировании. Используя ссылку детализации из предыдущего примера, можно выполнить вызов метода детализации:
// Invoking a grain method asynchronously
Task joinGameTask = player.JoinGame(this);
// The await keyword effectively makes the remainder of the
// method execute asynchronously at a later point
// (upon completion of the Task being awaited) without blocking the thread.
await joinGameTask;
// The next line will execute later, after joinGameTask has completed.
players.Add(playerId);
Можно объединить две или более Tasks
; Операция соединения создает новый Task
, который разрешается после завершения всех составляющих Task
. Этот шаблон удобен, когда детализация требует запуска нескольких вычислений и ожидает завершения всех из них, прежде чем продолжать. Например, детализация внешнего интерфейса, которая создает веб-страницу, состоящие из нескольких частей, может выполнять несколько внутренних вызовов, по одному для каждой части и принимающую Task
для каждого результата. В таком случае гранок будет ожидать присоединение всех этих Tasks
объектов; при разрешении объединения Task
отдельные Task
объекты были завершены, и все данные, необходимые для форматирования веб-страницы, были получены.
Пример
List<Task> tasks = new List<Task>();
Message notification = CreateNewMessage(text);
foreach (ISubscriber subscriber in subscribers)
{
tasks.Add(subscriber.Notify(notification));
}
// WhenAll joins a collection of tasks, and returns a joined
// Task that will be resolved when all of the individual notification Tasks are resolved.
Task joinedTask = Task.WhenAll(tasks);
await joinedTask;
// Execution of the rest of the method will continue
// asynchronously after joinedTask is resolve.
Класс граней может при необходимости переопределять OnActivateAsync и OnDeactivateAsync виртуальные методы; они вызываются средой выполнения Orleans при активации и деактивации каждого гранулярности класса. Это дает коду детализации возможность выполнения дополнительных операций инициализации и очистки. Исключение, OnActivateAsync
вызванное ошибкой процесса активации.
Хотя OnActivateAsync
, если переопределено, всегда вызывается как часть процесса активации детализации, OnDeactivateAsync
не гарантируется, что она будет вызываться во всех ситуациях, например, в случае сбоя сервера или другого аномального события. По этой причине приложения не должны полагаться на OnDeactivateAsync
выполнение критически важных операций, таких как сохранение изменений состояния. Они должны использовать его только для наиболее эффективного выполнения операций.
Обучение
Модуль
Создание первого приложения Орлеана с помощью ASP.NET Core 8.0 - Training
Узнайте, как создавать облачные распределенные приложения с помощью Орлеана.