質問

Python では、yield キーワードはプッシュ コンテキストとプル コンテキストの両方で使用できます。C# でプル コンテキストを実行する方法は知っていますが、プッシュを実現するにはどうすればよいでしょうか。Python から C# で複製しようとしているコードを投稿します。

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

ここで、お気づきのように、コルーチンが利用可能な場合は、「プッシュ」スタイルと「プル」スタイルのイテレータの両方を簡単に構築できます。(または、Thomas が指摘しているように、継続を使用してビルドすることもできます。) C# の現在のバージョンには、真のコルーチン (または継続) がありません。しかし、私たちはユーザーが周囲で感じる苦痛を非常に懸念しています。 非同期プログラミング.

ファイバーベースのコルーチンをファーストクラスの言語機能として実装することは、非同期プログラミングを容易にするために使用できる可能性のある手法の 1 つですが、これは現在研究中の多くのアイデアのうちの 1 つにすぎません。コルーチンが他のものよりも優れた仕事をする、本当に堅実で素晴らしいシナリオ (リアクティブ フレームワークを含む) がある場合は、それについて詳しく聞きたいと思っています。人々が非同期プログラミングで直面している実際の問題について、より現実的なデータがあればあるほど、良い解決策を思いつく可能性が高くなります。ありがとう!

アップデート:最近、コルーチンのような非同期制御フローを C# および VB の次のバージョンに追加することを発表しました。ダウンロードできる Community Technology Preview エディションを使用して、自分で試すことができます。 ここ.

他のヒント

C#の一般的なのコルーチンはありません。一般的な共ルーチンがコルーチンが独自のスタックを有する場合、すなわち、それは、他のメソッドを呼び出すことができ、これらの方法は、「収率」値缶です。一般的なコルーチンの実装は、スタックといくつかのスマートなものを作る可能性がアップして、ヒープ上のスタックフレーム(ローカル変数が含まれている隠された構造)を割り当てることを含むが必要です。これは、いくつかの言語は、(例えばスキーム)を行い、行うことができますが、右のそれを行うには、ややトリッキーです。また、多くのプログラマが理解しにくい機能を見つけます。

一般のコルーチンはスレッドをエミュレートすることができます。各スレッドは独自のスタックを持っています。コルーチンのセットアップでは、両方のスレッド(最初の発信者と共同ルーチンのスレッド)は、彼らが実際に同時に実行することはありません、コントロールを交互に表示します。 「収率」機構は、2つのスレッド間で交換され、そのようなものとして、それは(同期、OSカーネルスケジューラを介して往復...)高価です。また、メモリリークの余地は(コルーチンが明示的に待機しているスレッドが永遠に固執する、「停止」しなければならない)があります。したがって、これはめったに行われません。

C#のイテレータのと呼ばれるbastardizedダウンコルーチン機能を提供します。 C#コンパイラは、自動的にローカル変数は、クラス・フィールドになっと、特定の状態クラスにイテレータコードに変換します。降伏VMレベル、平野returnで、それからです。そのようなものは、長い「収率」はイテレータコード自体からではなく、その反復子コード呼び出すメソッドから実行されるようになんとかです。 C#のイテレータは、すでに多くのユースケースをカバーし、C#の設計者は、継続するへの道をさらに行くために不本意でした。いくつかの皮肉な人々は、フル機能の継続を実装するその大敵のJava(効率的な継続が実現可能であるが、これはGCとJITコンパイラでかなりの作業が必要です)ほど効率的であることから、C#のを妨げているということな状態に熱心です。

@NickLarsenおかげで、あなたは私がMSを導入したことを新しいもの、IObservableインターフェイスを覚えています。

助けました

リンク http://msdn.microsoft.com /en-us/library/dd783449(VS.100).aspxする

実際には.NETは、実際に、それは完全にOSレベルのスレッドから.NETレベルスレッドの概念を切り離し、スレッドの親和性について「間違った仮定を」ことはありません。

何をする必要がありことはあなたの繊維との論理的な.NETのスレッド状態を関連付けている(あなたがAPIのホスティングCLRを必要とするためではなく、あなたが直接、独自のアプリケーションから必要とされるものを使用することができますホストを自分で書く必要はありません)そしてすべてが、ロックの追跡は、例外処理が再び正常に動作します。

の例では、ここで見つけることができます: http://msdn.microsoft。 COM / EN-US /雑誌/ cc164086.aspxする

ところでモノ2.6ローレベルコルーチンのサポートが含まれており、簡単にすべてのより高いレベルプリミティブを実装するために使用することができる。

私は.NETのファイバベースのAPIを見てみたい。

私が呼び出す/ Pを通じてC#でネイティブ繊維APIを使用しようとしましたしばらく前、しかし、実行時の例外処理は、(間違って)スレッドベースの仮定を行っているので、物事が壊れた(ひどく)例外が起こったときます。

ファイバベースのコルーチンAPIのための一つの「キラーアプリは」ゲームプログラミングです。 AIの特定の種類は、あなたが意志のタイムスライスのことを「軽量」スレッドが必要です。例えば、ゲームの挙動の木は、判定スライスがアップしている時に、発信者に協力し降伏バックにAIコードを許可する「パルス」の決定コードする機能、フレーム毎に、必要としています。これは、ハードスレッドを実装することが可能であるが、はるかに、はるかに複雑ます。

真の繊維ユースケースが主流ではありませんしながら、だから、彼らは間違いなく存在し、繊維・サブシステム内の既存のバグが働いた場合は、私たちの.Netコーダーの小さなニッチが激しく応援します。

さて、私は 1 つのスレッドだけでコルーチンを管理するための完全なライブラリを開発してみました。難しい部分は、コルーチン内でコルーチンを呼び出してパラメータを返すことでしたが、最終的にはかなり良い結果に達しました ここ. 。唯一の警告は、I/O 操作のブロックはタスクを通じて行う必要があり、すべての "return" を "yield return" に置き換える必要があることです。このライブラリに基づくアプリケーション サーバーを使用すると、IIS に基づく標準の async/await で行われたリクエストをほぼ 2 倍にすることができました。(自宅で試すには、github で Node.Cs と Node.Cs.Musicstore を探してください)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top