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

StackOverflow https://stackoverflow.com/questions/2493294

Вопрос

В Python ключевое слово урожайность можно использовать как в контекстах push, так и в контекстах pull. Я знаю, как сделать контекст pull в С#, но как мне добиться push.Я публикую код, который пытаюсь воспроизвести на С# из 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"
Это было полезно?

Решение

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

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

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

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

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

Другие советы

С# не имеет общий совместные программы.Общая сопрограмма – это когда сопрограмма имеет свой собственный стек, т.е.он может вызывать другие методы, и эти методы могут «выдавать» значения.Реализация общих сопрограмм требует выполнения некоторых умных действий со стеками, возможно, вплоть до размещения фреймов стека (скрытых структур, содержащих локальные переменные) в куче.Это можно сделать, некоторые языки это делают (например.Схема), но сделать это правильно довольно сложно.Кроме того, многим программистам эту функцию сложно понять.

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

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

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

связь http://msdn.microsoft.com/en-us/library/dd783449(VS.100).aspx

На самом деле .NET не делает «неправильных предположений» о сходстве потоков, фактически он полностью отделяет понятие потока уровня .NET от потока уровня ОС.

Что вам нужно сделать, так это связать логическое состояние потока .NET с вашим волокном (для этого вам нужны API-интерфейсы хостинга CLR, но вам не нужно писать хост самостоятельно, вы можете использовать те, которые необходимы непосредственно из вашего собственного приложения) и все такое. отслеживание блокировок, обработка исключений снова работает нормально.

Пример можно найти здесь: http://msdn.microsoft.com/en-us/magazine/cc164086.aspx

Кстати, Mono 2.6 содержит поддержку сопрограмм низкого уровня и может использоваться для простой реализации всех примитивов более высокого уровня.

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

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

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

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

Что ж, я попробовал разработать полную библиотеку для управления сопрограммами только с одним потоком.Сложнее всего было вызывать сопрограммы внутри сопрограмм... и возвращать параметры, но в конце концов я достиг довольно хорошего результата. здесь.Единственное предупреждение заключается в том, что блокирование операций ввода-вывода должно выполняться с помощью задач, а все «возврат» должны быть заменены на «возврат доходности».С сервером приложений, основанным на этой библиотеке, я смог почти удвоить количество запросов, сделанных с помощью стандартного async/await на основе IIS.(Найдите Node.Cs и Node.Cs.Musicstore на github, чтобы попробовать дома)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top