2016-09-25 9 views
0

自分のWebサービスとの通信を試みているアプリケーションを表す状態マシンをカプセル化するクラスを作成しています。基本的な状態は、切断、接続、接続、資格情報の要求です。 Rxを使ってBehaviorSubjectを使って状態の変更を公開することについての良い学習経験があると思いました(うまくいけば、これは良い使い方ですか?)。この主題の私の州の1つは、「Requiring Credentials」です。ここでは、続行する前にユーザー名とパスワードを入力する必要があります。この演習の目的のために、私たちは、クラスは、Windowsコンソールアプリケーションでホストされていると仮定し、私はRxを使用してユーザー入力をリクエストするにはどうすればよいですか?

Console.WriteLine("Enter username"); 
var userName = Console.ReadLine(); 
Console.WriteLine("Enter password"); 
var password = Console.ReadLine(); 
私のRx BehaviorSubjectの結果

状態「RequiresCredentials」を押すと、それをユーザーに促したいとしましょうこの状態になるたびにこれに当たるはずです。

私は

public BehaviorSubject<ConnectionState> State { get; } 

(すなわち、観察可能なインタフェースか何かの後ろにそれを隠されていない)、それ自体としてBehaviorSubjectを露出し、ブロックする資格情報については、この要求をしたいしています。

このサブスクリプションに正しく加入するために、この入力を待ってから最後に制御を呼び出しスレッドに戻すために、どのプロセスを使用する必要がありますか?

答えて

2

タスクを待っていたり、待っていたり、非同期のものがある場合、Rxサブスクリプションコードは同じスレッドで監視され、ブロッキングコードを使用している場合はブロックされます。あなたが入力を気にしないならば、ストレートSubscribeを行うことができます。入力したユーザー名/パスワードを使用する場合は、Selectを使用できます。だから、これは動作します:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var subject = new BehaviorSubject<ConnectionState>(ConnectionState.Disconnected); 

     var getCredentials = subject.Where(cs => cs == ConnectionState.RequiresCredentials) 
      .Select(cs => 
      { 
       Console.WriteLine("Enter username"); 
       var userName = Console.ReadLine(); 
       Console.WriteLine("Enter password"); 
       var password = Console.ReadLine(); 
       return Tuple.Create(userName, password); 
      }); 
     using (var subscription = getCredentials.Subscribe()) 
     { 
      Console.WriteLine("Changing to Connecting..."); 
      subject.OnNext(ConnectionState.Connecting); 
      Console.WriteLine("Changing to RequiresCredentials..."); 
      subject.OnNext(ConnectionState.RequiresCredentials); 
      Console.WriteLine("Connected."); 
      subject.OnNext(ConnectionState.Connected); 
     } 

    } 
} 

enum ConnectionState 
{ 
    Disconnected, 
    Connected, 
    Connecting, 
    RequiresCredentials 
} 

それは次の出力を生成します。

Changing to Connecting... 
Changing to RequiresCredentials... 
Enter username 
ThisIsMyUserName 
Enter password 
ThisIsMyPassword 
Connected. 

これはしかし受信のかなり後方使用である:あなたが繰り返し、手続きの方法でのRxを使用するために探しているなら、なぜあなたはC#を使い、自分の複雑さを取り除いてみませんか?

+0

ありがとう@Shiomo最終的にこのクラスは、実際のアプリケーションコンソールとしてホストされているときは完全に非同期的な方法で使用されます。さまざまなXamarinベースのホストで使用されるPCLライブラリにあります。 Rxがバックグラウンドプロンプトに適していると思っています。また、私のより複雑なバックグラウンドdb sync'ingプロセスの他の部分を開始したり停止したりするのにも役立つでしょう。このアプリはオンとオフラインの両方で動作するように設計されています。私の例はちょっと基本的ですが、私はRxが後でうまくフィットすると信じていました。 –

関連する問題