C#如何聚合来自多个HTTP请求的结果?

时间:2018-03-08 14:05:47

标签: c# system.reactive microservices mediatr

我正在设计一个用C#和AspNetCore编写的应用程序,它需要向微服务发出多个HTTP请求并在返回控制器之前聚合结果。

我已经研究过MediatR管道,但似乎有限且不适合这种特殊情况。

我认为在地图领域有一些有用的东西可以减少但是很难找到一个我的开发人员可以快速开始的框架。

我们希望确保在一个或多个请求失败时终止聚合。

我使用工作线程创建了一个概念证明,例如

var results = await Task.WhenAll(task1, task2);

但是这并没有提供像MediatR开发人员可以轻松采用和单元测试的框架。

如果我的概念证明是使用Rx扩展和Observable.zip编写的,我想也是如此。我仍然很好奇,并希望在C#中找到使用Observable.zip的例子,类似于Netflix博客文章中所展示的内容

Reactive Programming in the Netflix API with RxJava

1 个答案:

答案 0 :(得分:0)

我已经构建了一个示例来帮助我理解在.NET中使用Rx的功能。

这是代码。

class Program
{
    static void Main(string[] args)
    {
        new Program().Run().Wait();
    }

    public async Task Run()
    {


        var resources =
            new List<string>
                {
                    "http://www.google.com"
                    ,"http://www.yahoo.com"
                    ,"http://cnn.com"
                    ,"http://microsoft.com"
                }
                .ToObservable()
                .Select(s => Observable.FromAsync(() => DownloadAsync(s)))
                .Concat()
                .Where(w => w.IsSuccessStatusCode)
                .Select(s => Observable.FromAsync(() => GetResources(s)))
                .Concat()
                .Where(w => w.Any())
                .SelectMany(s => s)
                .ToEnumerable()
                .OrderBy(o => o.Name);

        foreach (var re in resources)
        {
            Console.WriteLine(re.Name);
        }

        Console.ReadLine();
    }

    public async Task<HttpResponseMessage> DownloadAsync(string url)
    {
        var request = new HttpRequestMessage(HttpMethod.Get, url);

        var client = new HttpClient();

        return await client.SendAsync(request);
    }

    public async Task<IEnumerable<Resource>> GetResources(HttpResponseMessage message)
    {
        var ignoreContent = await message.Content.ReadAsStringAsync();
        return new List<Resource> { new Resource { Name = message.Headers.Date.ToString() } };
    }
}
public class Resource
{
    public string Name { get; set; }
}