2010-12-13 9 views
2

Reactive拡張機能について学習していて、自分のコードのいくつかを再調整しようとしています。Observable.FromAsyncPattern with UDPClient.EndReceiveとrefリモートエンドポイントパラメータ

UDPClient.EndReceiveref IPEndPointパラメータを取るので、私は現在、この作業を持っている:

UdpClient receiverUDP = new UdpClient(); 
receiverUDP.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
receiverUDP.EnableBroadcast = true; 
receiverUDP.Client.ExclusiveAddressUse = false; 
receiverUDP.Client.Bind(new IPEndPoint(IPAddress.Any, 1234)); 

IPEndPoint ep = null; 
var async = Observable.FromAsyncPattern<byte[]>(receiverUDP.BeginReceive, (i) => receiverUDP.EndReceive(i, ref ep)); 
var subscr = async().Subscribe(x => Console.WriteLine(ASCIIEncoding.ASCII.GetString(x))); 

私の加入者は、リモートIPEndPointにアクセスする必要がある場合はどう?私の現在の化身では、私はイベントを使用して、byte[]IPEndPointをラップするカスタムクラスを返します。私は私の人生のためにはできません、Rxでこれを行う方法を考えてください。行うには少し単純、そしてより多くの近代的な方法があります、他の誰のために

private IObservable<RemoteData> GetRemoteDataAsync() 
{ 
    return Observable.Defer(() => 
    { 
     UdpClient receiverUDP = new UdpClient(); 
     receiverUDP.Client.SetSocketOption(SocketOptionLevel.Socket, 
      SocketOptionName.ReuseAddress, true); 
     receiverUDP.EnableBroadcast = true; 
     receiverUDP.Client.ExclusiveAddressUse = false; 
     receiverUDP.Client.Bind(new IPEndPoint(IPAddress.Any, 1234)); 

     IPEndPoint ep = null; 
     return Observable.FromAsyncPattern<byte[]>(
        receiverUDP.BeginReceive, 
        (i) => receiverUDP.EndReceive(i, ref ep) 
       )() 
       .Select(bytes => new RemoteData(bytes, ep)); 
    }); 
} 

答えて

3

を探して:

+0

これを行う最新の方法でこれを正しい答えにしました... – Tim

6

すでにbyte[]IPEndPointのためのラッパークラスを作成した場合、なぜSelectを使用してシーケンスとしてそれを返しませんこれはReceiveAsync使用:

public static IObservable<UdpReceiveResult> UdpStream(IPEndPoint endpoint) 
{ 
    return Observable.Using(() => new UdpClient(endpoint), 
     udpClient => Observable.Defer(() => 
      udpClient.ReceiveAsync().ToObservable()).Repeat()); 
} 

あなたはIPAddress.Anyでそれを呼び出すことができます。

var stream = UdpStream(new IPEndPoint(IPAddress.Any, 514)); 

を入力し、Selectを使用して、ストリームを任意のタイプに投影します。

+0

'System.Func >' に変更 – Tim

+0

'を選択' の定義が含まれていません: VAR FUNC = Observable.FromAsyncPattern ( receiverUDP.BeginReceive、 (I)=> receiverUDP.EndReceiveを(i、ref ep) ); 戻り値func()。(bytes => new UDPMessage(bytes、ep)); – Tim

+0

良い点、私は元の例にメソッド呼び出しを追加しました –