Реализация сценариев NPC без сохранения состояния с сопрограммами / C # 5 ждет - PullRequest
1 голос
/ 29 декабря 2011

Я пытаюсь реализовать скрипты NPC, используя новую функцию C # await. Это мое доказательство концепции.

В NPC.cs вы можете увидеть этот фрагмент:

public async void Run(INPC npc)
{
    npc.Say("Hello!");
    await npc.WaitForOk();
    npc.Say("This is an example of some weird crap.");
    await npc.WaitForOk();
    npc.Say("Bye.");
    await npc.WaitForOk();
}

В реальном примере сценарий будет реализован на языке сценариев, таком как IronPython. Несмотря на то, что он может поддерживать ключевые слова async / await в будущем, необходимость делать это для каждого звонка очень хлопотна и раздражает.

Я пытался заставить другой метод быть асинхронным и выполнять ожидание, а сценарий просто вызывал его, но из-за способа, которым работает async / await, метод сценария (Run) просто продолжал бы без паузы / блокировки.

Есть ли способ избежать необходимости делать метод сценария асинхронным и использовать await перед каждым вызовом, сохраняя при этом функциональность, подобную сопрограмме?

Кроме того, если есть лучшее решение, которое уже доступно, чем использование async / await, в то же время поточно-ориентированное, выделите его.

Спасибо!

Ответы [ 2 ]

1 голос
/ 30 декабря 2011

Я не уверен, почему ты так стараешься избежать await.Я думаю, что это хорошая идея, требовать его для такого рода кода, потому что было бы трудно сказать, что код на самом деле делает иначе.Поэтому я считаю, что использование await таким способом, вероятно, является лучшим вариантом.

Кроме того, это хорошая идея, если вы можете избегать async void методов, так как вы не можете перехватить исключения, которые они выдают.

Я могу представить, что есть способы избежать написания async, например:

npc.AddAction(n => n.Say("Hello!"))
   .AddAction(n => n.WaitForOk())
   .AddAction(n => n.Say("This is an example of some weird crap."))
   .AddAction(n => n.WaitForOk());

npc.Run();

Здесь Run() обрабатывает список действий, созданных с использованием AddAction() и использует await где необходимо.

Но я сомневаюсь, что вы можете сделать это так же просто, как ваш код с await s.(Кроме того, реализация любого вида потока управления в коде, подобном этому, сделает его действительно нечитаемым.)

1 голос
/ 29 декабря 2011

Это очень интересное использование для async / await.

Я собрал много вопросов, связанных с синтаксисом со всего Интернета, в одну из моих публикаций в блоге . Короче говоря, есть веские причины, по которым async и await оба необходимы.

Если вы хотите добавить состояние к своим NPC, рассмотрите возможность использования подхода, основанного на наблюдателе ( Rx ). Этот подход способен к сложным взаимодействиям, а также может позволить параллельное выполнение различных NPC.

Вы также можете создавать свои NPC для задач пула потоков, которые довольно эффективны - когда они блокируются, ЦП становится доступным для других задач.

...