Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.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/3/gwt/3.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# 被动扩展Observerable.fromsync:如何等待异步操作完成_C#_System.reactive - Fatal编程技术网

C# 被动扩展Observerable.fromsync:如何等待异步操作完成

C# 被动扩展Observerable.fromsync:如何等待异步操作完成,c#,system.reactive,C#,System.reactive,在我的应用程序中,我从消息总线rabbitmq获取事件,但实际上这并不重要。这些事件的处理需要相当长的时间,而且这些事件是以突发方式产生的。一次只能处理一个事件。为了实现这一点,我使用Rx来序列化事件并异步执行处理,以避免阻塞生产者 以下是简化的示例代码: static void Main(string[] args) { var input = Observable.Interval(TimeSpan.FromMilliseconds(500)); var subscription

在我的应用程序中,我从消息总线rabbitmq获取事件,但实际上这并不重要。这些事件的处理需要相当长的时间,而且这些事件是以突发方式产生的。一次只能处理一个事件。为了实现这一点,我使用Rx来序列化事件并异步执行处理,以避免阻塞生产者

以下是简化的示例代码:

static void Main(string[] args)
{
   var input = Observable.Interval(TimeSpan.FromMilliseconds(500));
   var subscription = input.Select(i => Observable.FromAsync(ct => Process(ct, i)))
                           .Concat()
                           .Subscribe();

   Console.ReadLine();
   subscription.Dispose();
   // Wait until finished?
   Console.WriteLine("Completed");
}

private static async Task Process(CancellationToken cts, long i)
{
   Console.WriteLine($"Processing {i} ...");
   await Task.Delay(1000).ConfigureAwait(false);
   Console.WriteLine($"Finished processing {i}");
}
示例应用程序正在处理订阅,然后应用程序终止。但在此示例中,应用程序正在终止,而订阅之前收到的最后一个事件仍在处理中


问题:在处理订阅后,等待处理最后一个事件的最佳方式是什么?我仍然在试图把我的头脑集中在异步接收的东西上。我想有一个相当简单的方法来做到这一点,我只是没有看到现在

如果你能找到一个简单快捷的解决方案,适用于像这样的简单情况,那么你可以等待IObservable,而不是订阅它。如果要接收类似订阅的通知,请在最后等待之前使用Do操作符:


如果您可以使用一个快速简单的解决方案,该解决方案适用于像这样的简单情况,那么您可以等待IObservable,而不是订阅它。如果要接收类似订阅的通知,请在最后等待之前使用Do操作符:


多亏了Theodor的建议,我现在找到了一个适合我的解决方案:

static async Task Main(string[] args)
{
    var inputSequence = Observable.Interval(TimeSpan.FromMilliseconds(500));
    var terminate = new Subject<Unit>();
    var task = Execute(inputSequence, terminate);

    Console.ReadLine();
    terminate.OnNext(Unit.Default);
    await task.ConfigureAwait(false);
    Console.WriteLine($"Completed");
    Console.ReadLine();
}

private static async Task Process(CancellationToken cts, long i)
{
    Console.WriteLine($"Processing {i} ...");
    await Task.Delay(1000).ConfigureAwait(false);
    Console.WriteLine($"Finished processing {i}");
}

private static async Task Execute(IObservable<long> input, IObservable<Unit> terminate)
{
    await input
          .TakeUntil(terminate)
          .Select(i => Observable.FromAsync(ct => Process(ct, i)))
          .Concat();
}

多亏了Theodor的建议,我现在找到了一个适合我的解决方案:

static async Task Main(string[] args)
{
    var inputSequence = Observable.Interval(TimeSpan.FromMilliseconds(500));
    var terminate = new Subject<Unit>();
    var task = Execute(inputSequence, terminate);

    Console.ReadLine();
    terminate.OnNext(Unit.Default);
    await task.ConfigureAwait(false);
    Console.WriteLine($"Completed");
    Console.ReadLine();
}

private static async Task Process(CancellationToken cts, long i)
{
    Console.WriteLine($"Processing {i} ...");
    await Task.Delay(1000).ConfigureAwait(false);
    Console.WriteLine($"Finished processing {i}");
}

private static async Task Execute(IObservable<long> input, IObservable<Unit> terminate)
{
    await input
          .TakeUntil(terminate)
          .Select(i => Observable.FromAsync(ct => Process(ct, i)))
          .Concat();
}

RX有一个内置的功能。您是否可以选择使用ObserveOn而不是使用async?请参阅其他问题,如RX具有的内置功能。您是否可以选择使用ObserveOn而不是使用async?请参阅其他问题,如感谢您的建议。我会接受一个快速简单的解决方案,但不会等待。但你不能从我的问题中知道这一点:。但基本上是非常相似的。再次感谢。这帮了我很大的忙,我当然会接受你的回答。你也可以直接等待你的观察结果“等待”完成。谢谢你的建议。我会接受一个快速简单的解决方案,但不会等待。但你不能从我的问题中知道这一点:。但基本上是非常相似的。再次感谢。这帮了我很大的忙,我当然会接受你的答案。你也可以直接等待你的观察对象“等待”完成,而不是阻塞。