Как можно сделать Сопрограммы с помощью C#?

В Python ключевое слово урожая может использоваться и в контекстах нажатия и в получения по запросу, я знаю, как сделать контекст получения по запросу в c#, но как я достиг бы нажатия. Я отправляю код, который я пытаюсь копировать в c# из Python:

def coroutine(func):
  def start(*args,**kwargs):
    cr = func(*args,**kwargs)
    cr.next()
    return cr
  return start

@coroutine
def grep(pattern):
  print "Looking for %s" % pattern
  try:
    while True:
      line = (yield)
      if pattern in line:
        print line,
  except GeneratorExit:
    print "Going away. Goodbye"
10
задан T. Bergemann 19 June 2012 в 21:56
поделиться

6 ответов

Если вам нужна «наблюдаемая коллекция», то есть коллекция, которая передает вам результаты, а не позволяет потребителю извлекать их, тогда вы, вероятно, захотите изучить расширения Reactive Framework. Вот статья об этом:

http://www.infoq.com/news/2009/07/Reactive-Framework-LINQ-Events

Как вы заметили, вы можете создавать как "push", так и " легко вытащить итераторы стиля, если у вас есть сопрограммы. (Или, как указывает Томас, вы также можете построить их с продолжениями.) В текущей версии C # у нас нет настоящих сопрограмм (или продолжений). Однако нас очень беспокоит боль, которую испытывают пользователи асинхронного программирования .

Реализация сопрограмм на основе волокон в качестве первоклассной языковой возможности - это один из методов, который, возможно, можно было бы использовать для упрощения асинхронного программирования, но это лишь одна возможная идея из многих, которые мы в настоящее время исследуем. Если у вас есть действительно отличный сценарий, в котором сопрограммы работают лучше, чем что-либо еще, включая реактивный фреймворк, то я хотел бы услышать об этом больше. Чем более реалистичны данные о реальных проблемах, с которыми люди сталкиваются при асинхронном программировании, тем больше у нас шансов найти хорошее решение. Спасибо!

ОБНОВЛЕНИЕ: Недавно мы объявили, что добавляем асинхронные потоки управления, подобные сопрограммам, в следующую версию C # и VB. Вы можете попробовать это сами с помощью нашей версии Community Technology Preview, которую вы можете загрузить здесь .

14
ответ дан 3 December 2019 в 15:35
поделиться

спасибо @NickLarsen, вы помогли мне вспомнить новый материал, который представила MS, - интерфейс IObservable.

ссылка http://msdn.microsoft.com/en-us/library/dd783449 (VS.100) .aspx

3
ответ дан 3 December 2019 в 15:35
поделиться
3
ответ дан 3 December 2019 в 15:35
поделиться

В C# нет общих совместных программ. Общая совместная программа - это когда совместная программа имеет свой собственный стек, т.е. она может вызывать другие методы, и эти методы могут "выдавать" значения. Реализация общих совместных маршрутов требует некоторых умных действий со стеком, возможно, вплоть до выделения стековых фреймов (скрытых структур, содержащих локальные переменные) на куче. Это можно сделать, некоторые языки делают это (например, Scheme), но сделать это правильно довольно сложно. Кроме того, многие программисты находят эту возможность сложной для понимания.

Общие совместные программы могут быть эмулированы с помощью потоков. Каждый поток имеет свой собственный стек. При установке совместной программы оба потока (первоначальный вызывающий и поток для совместной программы) будут чередовать управление, они никогда не будут выполняться одновременно. Механизм "выхода" - это обмен между двумя потоками, и как таковой он является дорогостоящим (синхронизация, обход через ядро ОС и планировщик...). Кроме того, существует много возможностей для утечки памяти (совместная программа должна быть явно "остановлена", иначе ожидающий поток будет торчать вечно). Таким образом, это делается редко.

C# предоставляет урезанную функцию совместных маршрутов под названием итераторы. Компилятор C# автоматически преобразует код итератора в определенный класс состояния, при этом локальные переменные становятся полями класса. Тогда на уровне виртуальной машины возврат становится обычным return. Такое возможно при условии, что "выход" выполняется из самого кода итератора, а не из метода, который код итератора вызывает. Итераторы C# уже покрывают многие случаи использования, и разработчики C# не захотели идти дальше по пути продолжений. Некоторые язвительные люди стремятся заявить, что реализация полнофункциональных континуумов помешала бы C# быть таким же эффективным, как его заклятый враг Java (эффективные континуумы осуществимы, но это требует довольно большой работы с GC и JIT-компилятором).

7
ответ дан 3 December 2019 в 15:35
поделиться

Мне бы хотелось увидеть API на основе волокна для .Net.

Некоторое время назад я пытался использовать собственный API-интерфейс Fibre в C # через p / invoke, но поскольку обработка исключений во время выполнения (неправильно) делает предположения на основе потоков, все ломалось (плохо), когда возникали исключения.

Одним из «убийственных приложений» для API сопрограмм на основе волокна является программирование игр; для определенных типов ИИ требуется «легкий» поток, который можно разрезать по времени по желанию. Например, деревья поведения игры требуют способности «пульсировать» код решения каждый кадр, позволяя коду ИИ совместно уступать вызывающему при выполнении среза решения. Это можно реализовать с помощью жестких потоков, но намного сложнее.

Таким образом, хотя настоящие варианты использования оптоволокна не являются широко распространенными, они определенно существуют, и небольшая ниша из нас, кодировщиков .Net сильно обрадуется, если бы существующие ошибки в подсистеме оптоволокна были устранены.

0
ответ дан 3 December 2019 в 15:35
поделиться

Actually .NET does not make "incorrect assumptions" about thread affinity, in fact it totally decouples the notion of a .NET level thread from the OS level thread.

What you have to do is associate a logical .NET thread state with your fiber ( for that you need the CLR Hosting API's but you don'T need to write a host yourself you can use those needed from your own application directly ) and everything, lock tracking, exception handling works normally again.

An example can be found here: http://msdn.microsoft.com/en-us/magazine/cc164086.aspx

Btw Mono 2.6 contains low level Coroutine support and can be used to implement all higher level primitives easily.

1
ответ дан 3 December 2019 в 15:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: