Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.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#_Roslyn_Rx.net - Fatal编程技术网

C# 为什么重播方法会阻止可观察集合的完成?

C# 为什么重播方法会阻止可观察集合的完成?,c#,roslyn,rx.net,C#,Roslyn,Rx.net,我有一个运行缓慢的任务要在项目列表上执行。 这就是我想要实现的目标: 应立即开始处理 最多N个并发任务 每个项目只能运行一次任务 所有订阅者都应该看到所有结果(无论他们何时订阅) 这是我的原型机-它按预期工作(LinqPad) 这是我的实际代码: sln.Projects = result .Projects .ToObservable() //Appears to be unnecessary .Select(p => Observ

我有一个运行缓慢的任务要在项目列表上执行。 这就是我想要实现的目标:

  • 应立即开始处理
  • 最多N个并发任务
  • 每个项目只能运行一次任务
  • 所有订阅者都应该看到所有结果(无论他们何时订阅)
  • 这是我的原型机-它按预期工作(LinqPad)

    这是我的实际代码:

        sln.Projects = result
            .Projects
            .ToObservable() //Appears to be unnecessary
            .Select(p => Observable.FromAsync(() => projectLoader.Load(p, sln)))
            .Merge(_maxConcurrent)
            .Replay(); 
    
         await sln.Projects; //Hangs forever if Replay is used
    
    “结果”是Microsoft.CodeAnalysisSolution

    我尝试了几种变体-
    Projects.ToList,带ToObservable和不带
    用虚拟加载替换了项目加载程序
    使用和不使用\u maxConcurrent运行

    这段代码在等待时永远挂起,我似乎看不出与原型在功能上有什么不同

    如果我删除重播,代码将按预期运行,但每个订阅者都会被命中

    有人知道这段代码有什么不同,以及重播方法为什么会影响这样的执行吗

    我开始怀疑这一定是订阅者的问题——但这不是我目前可以轻易提取出来验证的东西

    下面是可以工作的原始代码(但不起作用)


    原型与您实际使用代码之间的区别在于您存储可观察数据的方式。在原型中,它存储为局部变量,但在生产代码中,它保存在
    sln
    对象中

    为了能够为未来的用户重放可观察到的所有信号,它无法完成。我认为它使用局部变量的原因与局部作用域有关,但我还没有深入研究

    如果在Linqpad中运行以下命令,您将看到在对象中存储可观察对象会改变行为

    async Task Main()
    {
         int throttle = 3;
        var container = new Container();
    
        container.Results =
            Enumerable.Range(1, 20)
                .ToObservable()
                .Select(n => Observable.FromAsync(() => DoSomething(n)))
                .Merge(throttle)
                .Replay();
    
        var res = await container.Results;
    
        res.Dump("Res");
    }
    
    public async Task DoSomething(int n)
    {
        Console.WriteLine($"Starting {n}");
        await Task.Delay(100);
        Console.WriteLine($"Ending {n}");
    }
    
    public class Container
    {
        public IObservable<Unit> Results { get; set; }
    }
    
        sln.Projects = result.Projects
            .Select(p => projectLoader.Load(p, sln))
            .ToList()
            .Select(p => p.ToObservable())
            .Merge();
    
    async Task Main()
    {
         int throttle = 3;
        var container = new Container();
    
        container.Results =
            Enumerable.Range(1, 20)
                .ToObservable()
                .Select(n => Observable.FromAsync(() => DoSomething(n)))
                .Merge(throttle)
                .Replay();
    
        var res = await container.Results;
    
        res.Dump("Res");
    }
    
    public async Task DoSomething(int n)
    {
        Console.WriteLine($"Starting {n}");
        await Task.Delay(100);
        Console.WriteLine($"Ending {n}");
    }
    
    public class Container
    {
        public IObservable<Unit> Results { get; set; }
    }
    
    async Task Main()
    {
         int throttle = 3;
        var container = new Container();
    
        container.Results =
            Enumerable.Range(1, 20)
            .ToObservable()
            .Select(n => Observable.FromAsync(() => DoSomething(n)))
            .Merge(throttle)
            .Replay();
    
        container.Results.Connect();
    
        (await container.Results).Dump("1");
        (await container.Results).Dump("2");
    }
    
    public async Task DoSomething(int n)
    {
        Console.WriteLine($"Starting {n}");
        await Task.Delay(100);
        Console.WriteLine($"Ending {n}");
    }
    
    public class Container
    {
        public IConnectableObservable<Unit> Results { get; set; }
    }