为什么C#Rx Subscribe()函数不能与“ async”关键字一起使用?

问题描述 投票:1回答:1

我有此代码段:

static void Main(string[] args)
{
    Observable.Range(1, 5).Subscribe(async x => await DoTheThing(x));
    Console.WriteLine("done");
}

static async Task DoTheThing(int x)
{
    await Task.Delay(TimeSpan.FromSeconds(x));
    Console.WriteLine(x);
}

我希望它会循环5次,并且每次循环后都会有一行打印为

1
2
3
4
5

但是令人惊讶的是,这将打印“完成”并立即终止。似乎async + await没有等待Task.Delay并退出。

语义似乎没有问题,所以我在哪里订阅或异步出错了,如何解决它以满足我从Rx调用异步任务的请求?

谢谢。

c# asynchronous async-await system.reactive subscribe
1个回答
5
投票

这不是阻塞,因为很好-异步。您的代码生成五个任务,这些任务并行运行,并在不同的时间完成。

但是它们不会阻止Main功能。如果仅将Console.ReadKey()添加为最后一行,则会看到您的代码确实在后台运行。打印。

static void Main(string[] args)
{
    Observable.Range(1, 5).Subscribe(async x => await DoTheThing(x));
    Console.WriteLine("done");
    Console.ReadKey();
}

但是假设您要等到所有步骤都完成之后。那怎么办?

当然,有.Wait(),但这很阻塞。让我们以可观察的方式观察我们所有的任务。

我们将使用C#7的async Main

static async Task Main(string[] args)
{
    await Observable.Range(1, 5)
        .Select(x => DoTheThing(x).ToObservable())
        .Merge();                

    Console.WriteLine("done");
}

这完全符合您的预期。

© www.soinside.com 2019 - 2024. All rights reserved.