Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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# 反应式扩展:将同步订阅转换为异步订阅_C#_Asynchronous_System.reactive - Fatal编程技术网

C# 反应式扩展:将同步订阅转换为异步订阅

C# 反应式扩展:将同步订阅转换为异步订阅,c#,asynchronous,system.reactive,C#,Asynchronous,System.reactive,我对一系列可观测数据进行了同步订阅,实现方式与这段代码类似: integers.Where(id => (id & 1) == 0).Subscribe(id => evenHandler.LRP(id, RandomDelay())); integers.Where(id => (id & 1) == 1).Subscribe(id => oddHandler.LRP(id, RandomDelay())); 问题是操作被阻塞,因此您以如下场景结束:

我对一系列可观测数据进行了同步订阅,实现方式与这段代码类似:

integers.Where(id => (id & 1) == 0).Subscribe(id => evenHandler.LRP(id, RandomDelay()));
integers.Where(id => (id & 1) == 1).Subscribe(id => oddHandler.LRP(id, RandomDelay()));
问题是操作被阻塞,因此您以如下场景结束:

OddHandler running with ID 1 for 331ms...
EvenHandler running with ID 2 for 651ms...
OddHandler running with ID 3 for 391ms...
EvenHandler running with ID 4 for 633ms...
OddHandler running with ID 5 for 197ms...
我希望操作异步运行,但我无权访问公开方法
LRP
IHandler
接口。在做了一些研究之后,似乎至少有两种使用RX的方法:

方法1:

integers.Where(id => (id & 1) == 0)
    .Select(async id => await Task.Run(() => evenHandler.LRP(id, RandomDelay())))
    .Subscribe();

integers.Where(id => (id & 1) == 1)
    .Select(async id => await Task.Run(() => oddHandler.LRP(id, RandomDelay())))
    .Subscribe();
方法2:

integers.Where(id => (id & 1) == 0)
    .SelectMany(id => Observable.StartAsync(
        async () => await Task.Run(() => evenHandler.LRP(id, RandomDelay())))
    ).Subscribe();

integers.Where(id => (id & 1) == 1)
    .SelectMany(id => Observable.StartAsync(
        async () => await Task.Run(() => oddHandler.LRP(id, RandomDelay())))
    ).Subscribe();
两种方法似乎产生相同的结果

我的问题是:

  • 这两种技术的区别是什么
  • 完成我需要做的事情的推荐方法是什么
  • 我会远离方法1,因为它有点“破坏”Rx。当您在
    中等待
    时,选择,您正在使同步运算符执行异步工作。每当你想做一些异步的事情时,把它放在一个
    SelectMany
    SelectMany
    甚至直接接受
    任务

    在方法2中,您将
    任务
    包装在一个可观察对象中。我相信这与
    Observable.fromsync()
    非常相似。然而,创建一个
    任务
    ,然后将其转换为一个可观察的任务,这有点繁琐;你可以直接使用一个可观察的:

    integers.Where(id => (id & 1) == 0)
        .SelectMany(id => Observable.Start(
            () => evenHandler.LRP(id, RandomDelay()),
            ThreadPoolScheduler.Default))
        .Subscribe();
    
    integers.Where(id => (id & 1) == 1)
        .SelectMany(id => Observable.Start(
            () => oddHandler.LRP(id, RandomDelay()),
            ThreadPoolScheduler.Default))
        .Subscribe();
    
    这将创建一个可观察对象,当内部功完成时,该对象返回一个
    单元
    。我还指定它应该在
    TaskPoolScheduler
    上运行,这使得它在
    任务中运行