【问题标题】:Observable.FromAsyncPattern & UdpClient C#Observable.FromAsyncPattern & UdpClient C#
【发布时间】:2018-04-25 22:15:47
【问题描述】:

我希望能够使用响应式异步接收 udp 包。 我已经写了这段代码。

udpServer = new UdpClient(20000);
remoteEP = new IPEndPoint(IPAddress.Any, 20000);

var read = Observable.FromAsyncPattern(udpServer.BeginReceive, t => udpServer.EndReceive(t, ref remoteEP));

然后我使用这个函数并存储 IObservable 结果。

reader = read()
       .Do(s =>
       {
           Logs.Add(System.Text.Encoding.UTF8.GetString(s));
       })
       .DoOnError(ex => status = ex.Message; );

当我最终订阅时,操作只发生一次,然后观察者在完成时被处理。

我的问题来了:有没有办法让这段代码连续工作? 每次收到新日志时都接收“DO”操作?

侧边栏:只是想知道 Observable.FromAsyncPattern 有什么意义,如果我不能重用它,我最好静态键入 2 个方法作为开始和结束,而不是获得更多需要稍后处理的类实例的开销。

-im 也对所有其他不同的选项开放,除了使用 TPL。

【问题讨论】:

    标签: c# unity3d udpclient unirx


    【解决方案1】:

    试试这个:

    var query =
        Observable
            .Using(
                () => new UdpClient(new IPEndPoint(IPAddress.Any, 20000)),
                udpServer =>
                    Observable
                        .Defer(() =>
                            Observable
                                .FromAsync(() => udpServer.ReceiveAsync()))
                        .Repeat());
    

    您需要使用.Using 管理IDispose 资源,并且需要.Repeat 调用FromAsync。

    FromAsyncPattern 现已过时。


    如果您需要使用过时的FromAsyncPattern,请执行以下操作:

    var query =
        Observable
            .Using(
                () => new UdpClient(20000),
                udpServer =>
                    Observable
                        .Defer(() =>
                            Observable
                                .FromAsyncPattern(udpServer.BeginReceive, t => udpServer.EndReceive(t, ref remoteEP)))
                        .Repeat());
    

    【讨论】:

    • 这是否记录在任何地方?我的意思是,作为指南或其他东西。我几年前读的书(Rx 简介)甚至没有提到您以这种方式使用的一些 API,所以我认为它是相当新的。
    • @TanveerBadar - 不,除了.FromAsync 电话,这一切都是从 1.0 开始的。
    • @TanveerBadar - Using Defer Repeat
    • 谢谢,我一定是看的不够仔细。
    • 感谢您的宝贵时间。我仍在寻找一种使用过时调用的方法,因为我是统一的,使用 .net 3.5。
    【解决方案2】:

    这是因为观察者在给定集合上工作。从BeginReceive 返回的集合不同于再次调用它。使用您显示的代码,我并不感到惊讶它只工作一次。您需要为BeginReceive 提供一致的缓冲区,然后为该缓冲区订阅一个观察者,以便它每次都触发。也就是说,缓冲区在调用之间需要是相同的实例。

    【讨论】:

    • 我很想举一个例子来说明你的意思。我想照你说的做,但我似乎做不到。
    猜你喜欢
    • 2014-06-15
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    相关资源
    最近更新 更多