Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用RxExtensions停止侦听UDP套接字的正确方法_C#_Udp_System.reactive - Fatal编程技术网

C# 使用RxExtensions停止侦听UDP套接字的正确方法

C# 使用RxExtensions停止侦听UDP套接字的正确方法,c#,udp,system.reactive,C#,Udp,System.reactive,我需要监听UDP套接字,10秒后或缓冲区中的100项后,应该调用一些逻辑。一般来说,它工作正常,但我不知道如何正确停止监听插座 var ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234); var socket = new UdpClient(ip); var cancellationTokenSource = new CancellationTokenSource(); var observable = Observable

我需要监听UDP套接字,10秒后或缓冲区中的100项后,应该调用一些逻辑。一般来说,它工作正常,但我不知道如何正确停止监听插座

var ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234);
var socket = new UdpClient(ip);

var cancellationTokenSource = new CancellationTokenSource();
var observable =
  Observable
  .FromAsync(socket.ReceiveAsync)
  .DoWhile(() => !cancellationTokenSource.IsCancellationRequested)
  .Buffer(TimeSpan.FromSeconds(10), 100);

var subscribtion = observable.Subscribe(o =>
{
  //logic
});

//simulate close method from another thread
Task.Factory.StartNew(() =>
{
  Task.Delay(TimeSpan.FromSeconds(12)).Wait();
  cancellationTokenSource.Cancel();
  socket.Close();
  subscribtion.Dispose();
});
当我模拟关闭套接字时,存在一种情况,即缓冲区中存在一些无法处理的数据-有什么方法可以避免这种行为吗

当我以500毫秒的延迟从另一个进程发送一些消息时,其工作原理如下所示:

  • 20条信息将带来收入
  • 一些逻辑将是调用订户逻辑
  • 4条消息将带来收入
  • 将调用Simulate close方法

  • 当“关闭方法”将被调用时,我需要立即处理缓冲区中的所有数据并关闭应用程序,甚至不等待缓冲区超时。缓冲区延迟时间由用户定义,所以我不希望等待调用订户逻辑,因为这可能是一段相当长的时间。

    欢迎使用StackOverflow

    缓冲区方法的现有重载不支持时间、计数和门。但是当序列产生一个值时,会有一个重载触发缓冲区关闭。因此,我们将简单地通过合并所有缓冲区关闭条件的观察值来创建一个序列

    看看这个演示

    onTime
    将在指定的时间段后生成一个值

    onCount
    将在传递
    x
    项后生成其第一个值

    onClose
    将立即在subscribe上生成一个值-但在我们决定之前,我们不会连接到它

                var producer = Observable.Interval(TimeSpan.FromSeconds(0.2));
                var source = producer.Publish().RefCount();
    
                var onClose = Observable.Return(0L).Publish();
                var onTime = Observable.Timer(TimeSpan.FromSeconds(2));
                var onCount = source.Skip(10);
    
                var bufferClose = Observable.Merge(onClose, onTime, onCount);
    
            var subscription =
                source
                .Buffer(() => bufferClose)
                .Subscribe(list => Console.WriteLine(string.Join(",", list)));
    
                Console.WriteLine("Waiting for close");
                Console.ReadLine();
    
                onClose.Connect(); //signal
                subscription.Dispose();
    
                Console.WriteLine("Closed");
    
                Console.ReadLine();
    

    这将根据计数或时间生成输出,直到按下return键,当它立即关闭时,缓冲区中有可用的内容。

    您能提供一个详细的信息吗?我想运行一些代码来演示您的问题。然后就可以修好了。我要说的是,解决方案将不是混合第三方物流和Rx。Rx更强大,这是您应该关注的。感谢您的关注。也许我试着重新问我的问题,把更多的注意力放在Rx上。在我的示例中,我使用了带缓冲区的Observable方法。它每隔10秒或缓冲区中的100项通知订阅者。。但当有人关闭我的应用程序时,我有一个特殊的情况。它可能在未指定的时间内发生,因此,例如,如果它发生在距离最后一个订阅者通知的第三秒,并且缓冲区中存在一些数据,我必须再保持我的应用程序7秒钟,以处理缓冲区中的所有数据。有什么方法可以说是可观察类(按需)-停止观察者您的源并最后一次通知订阅者。“停止观察者您的源并最后一次通知订阅者”是什么意思?在Rx lanugage上,它被设置为可观察完成。明天我将尝试这个解决方案,但它看起来很有希望。谢谢你。@tom结果怎么样?